From 324a0a8151e2341d4ea7bdefc783594385615066 Mon Sep 17 00:00:00 2001 From: eliot-akira Date: Fri, 11 Oct 2024 18:11:29 +0200 Subject: [PATCH] Include React Bootstrap and examples; Start design tokens CLI --- dequal/alts.ts | 78 +++ dequal/index.ts | 84 +++ dequal/lite.ts | 29 + design-tokens-cli/chooseTransform.ts | 27 + .../example/tokens-layout/inset.tokens.json | 20 + .../example/tokens-layout/size.tokens.json | 88 +++ .../example/tokens-type/color.tokens | 50 ++ .../example/tokens-type/font-size.tokens.json | 40 ++ design-tokens-cli/example/tokens.config.json | 48 ++ design-tokens-cli/filterByGroup.ts | 17 + design-tokens-cli/findDuplicates.ts | 10 + design-tokens-cli/findTrueValues.ts | 28 + design-tokens-cli/flattenJSON.ts | 54 ++ design-tokens-cli/index.ts | 17 + design-tokens-cli/refToName.ts | 12 + design-tokens-cli/sortKeys.ts | 14 + design-tokens-cli/tests/filterByGroup.test.ts | 14 + .../tests/findTrueValues.test.ts | 15 + design-tokens-cli/tests/refToName.test.ts | 9 + design-tokens-cli/tests/sortKeys.test.ts | 14 + design-tokens-cli/tests/toCustomProps.test.ts | 19 + design-tokens-cli/tests/toESM.test.ts | 21 + design-tokens-cli/tests/toJSON.test.ts | 19 + design-tokens-cli/tests/toScssVars.test.ts | 17 + design-tokens-cli/transform.ts | 67 ++ .../transformers/toCustomProps.ts | 18 + design-tokens-cli/transformers/toESM.ts | 20 + design-tokens-cli/transformers/toJSON.ts | 15 + design-tokens-cli/transformers/toScssVars.ts | 15 + dom-helpers/activeElement.ts | 21 + dom-helpers/addClass.ts | 22 + dom-helpers/addEventListener.ts | 71 ++ dom-helpers/animate.ts | 138 ++++ dom-helpers/animationFrame.ts | 45 ++ dom-helpers/attribute.ts | 24 + dom-helpers/camelize.ts | 5 + dom-helpers/camelizeStyle.ts | 15 + dom-helpers/canUseDOM.ts | 5 + dom-helpers/childElements.ts | 10 + dom-helpers/childNodes.ts | 12 + dom-helpers/clear.ts | 16 + dom-helpers/closest.ts | 28 + dom-helpers/collectElements.ts | 17 + dom-helpers/collectSiblings.ts | 20 + dom-helpers/contains.ts | 15 + dom-helpers/css.ts | 51 ++ dom-helpers/filterEventHandler.ts | 16 + dom-helpers/getComputedStyle.ts | 14 + dom-helpers/getScrollAccessor.ts | 26 + dom-helpers/hasClass.ts | 19 + dom-helpers/height.ts | 17 + dom-helpers/hyphenate.ts | 5 + dom-helpers/hyphenateStyle.ts | 13 + dom-helpers/index.ts | 143 ++++ dom-helpers/insertAfter.ts | 20 + dom-helpers/isDocument.ts | 5 + dom-helpers/isInput.ts | 12 + dom-helpers/isTransform.ts | 28 + dom-helpers/isVisible.ts | 10 + dom-helpers/isWindow.ts | 10 + dom-helpers/listen.ts | 16 + dom-helpers/matches.ts | 23 + dom-helpers/nextUntil.ts | 14 + dom-helpers/offset.ts | 31 + dom-helpers/offsetParent.ts | 20 + dom-helpers/ownerDocument.ts | 8 + dom-helpers/ownerWindow.ts | 11 + dom-helpers/parents.ts | 12 + dom-helpers/position.ts | 46 ++ dom-helpers/prepend.ts | 20 + dom-helpers/querySelectorAll.ts | 14 + dom-helpers/remove.ts | 14 + dom-helpers/removeClass.ts | 34 + dom-helpers/removeEventListener.ts | 27 + dom-helpers/scrollLeft.ts | 9 + dom-helpers/scrollParent.ts | 42 ++ dom-helpers/scrollTo.ts | 47 ++ dom-helpers/scrollTop.ts | 9 + dom-helpers/scrollbarSize.ts | 23 + dom-helpers/siblings.ts | 12 + dom-helpers/text.ts | 30 + dom-helpers/toggleClass.ts | 18 + dom-helpers/transitionEnd.ts | 55 ++ dom-helpers/triggerEvent.ts | 21 + dom-helpers/types.d.ts | 8 + dom-helpers/width.ts | 13 + hooks/globals.d.ts | 68 ++ hooks/index.ts | 29 + hooks/useAnimationFrame.ts | 76 +++ hooks/useBreakpoint.ts | 161 +++++ hooks/useCallbackRef.ts | 32 + hooks/useCommittedRef.ts | 22 + hooks/useCustomEffect.ts | 93 +++ hooks/useDebouncedCallback.ts | 186 +++++ hooks/useDebouncedState.ts | 32 + hooks/useDebouncedValue.ts | 48 ++ hooks/useEventCallback.ts | 14 + hooks/useEventListener.ts | 37 + hooks/useFocusManager.ts | 115 ++++ hooks/useForceUpdate.ts | 24 + hooks/useGlobalListener.ts | 31 + hooks/useImage.ts | 78 +++ hooks/useImmediateUpdateEffect.ts | 3 + hooks/useIntersectionObserver.ts | 86 +++ hooks/useInterval.ts | 104 +++ hooks/useIsInitialRenderRef.ts | 31 + hooks/useIsomorphicEffect.ts | 20 + hooks/useMap.ts | 64 ++ hooks/useMediaQuery.tsx | 89 +++ hooks/useMergeState.ts | 48 ++ hooks/useMergeStateFromProps.ts | 20 + hooks/useMergedRefs.ts | 42 ++ hooks/useMountEffect.ts | 24 + hooks/useMounted.ts | 33 + hooks/useMutationObserver.ts | 98 +++ hooks/usePrevious.ts | 26 + hooks/useRafInterval.ts | 40 ++ hooks/useRefWithInitialValueFactory.ts | 25 + hooks/useResizeObserver.ts | 68 ++ hooks/useSafeState.ts | 41 ++ hooks/useSet.ts | 57 ++ hooks/useStableMemo.ts | 54 ++ hooks/useStateAsync.ts | 69 ++ hooks/useThrottledEventHandler.ts | 95 +++ hooks/useTimeout.ts | 79 +++ hooks/useToggleState.ts | 31 + hooks/useUpdateEffect.ts | 34 + hooks/useUpdateImmediateEffect.ts | 43 ++ hooks/useUpdateLayoutEffect.ts | 34 + hooks/useUpdatedRef.ts | 13 + hooks/useWillUnmount.ts | 14 + invariant/index.ts | 51 ++ license.txt | 13 +- package.json | 29 +- prop-types-extra/all.ts | 22 + prop-types-extra/componentOrElement.ts | 32 + prop-types-extra/deprecated.ts | 34 + prop-types-extra/elementType.ts | 28 + prop-types-extra/index.ts | 13 + prop-types-extra/isRequiredForA11y.ts | 20 + .../utils/createChainableTypeChecker.ts | 50 ++ react-examples/Accordion/AllCollapse.tsx | 34 + react-examples/Accordion/AlwaysOpen.tsx | 34 + react-examples/Accordion/Basic.tsx | 34 + .../Accordion/ContextAwareToggle.tsx | 54 ++ react-examples/Accordion/CustomToggle.tsx | 44 ++ react-examples/Accordion/Flush.tsx | 34 + react-examples/Alert/AdditionalContent.tsx | 21 + react-examples/Alert/Basic.tsx | 24 + react-examples/Alert/Dismissible.tsx | 23 + .../Alert/DismissibleControlled.tsx | 30 + react-examples/Alert/Link.tsx | 26 + react-examples/AsProp.tsx | 8 + react-examples/AsPropComponent.tsx | 17 + react-examples/Badge/Basic.tsx | 28 + react-examples/Badge/Button.tsx | 13 + react-examples/Badge/Pill.tsx | 35 + react-examples/Badge/Variations.tsx | 23 + react-examples/Breadcrumb.tsx | 15 + react-examples/Button/Active.tsx | 16 + react-examples/Button/Block.tsx | 16 + react-examples/Button/Disabled.tsx | 19 + react-examples/Button/Loading.tsx | 32 + react-examples/Button/OutlineTypes.tsx | 18 + react-examples/Button/Sizes.tsx | 26 + react-examples/Button/TagTypes.tsx | 14 + react-examples/Button/ToggleButton.tsx | 79 +++ .../Button/ToggleButtonGroupControlled.tsx | 31 + .../Button/ToggleButtonGroupUncontrolled.tsx | 34 + react-examples/Button/Types.tsx | 19 + react-examples/ButtonGroup/Basic.tsx | 14 + react-examples/ButtonGroup/Nested.tsx | 19 + react-examples/ButtonGroup/Sizes.tsx | 28 + react-examples/ButtonGroup/Toolbar.tsx | 52 ++ react-examples/ButtonGroup/ToolbarBasic.tsx | 22 + react-examples/ButtonGroup/Vertical.tsx | 45 ++ react-examples/Card/Basic.tsx | 20 + react-examples/Card/BgColor.tsx | 37 + react-examples/Card/BodyOnly.tsx | 11 + react-examples/Card/BodyShorthand.tsx | 7 + react-examples/Card/Border.tsx | 105 +++ react-examples/Card/Grid.tsx | 27 + react-examples/Card/Group.tsx | 51 ++ react-examples/Card/HeaderAndFooter.tsx | 20 + react-examples/Card/ImageAndText.tsx | 29 + react-examples/Card/ImgOverlay.tsx | 19 + react-examples/Card/KitchenSink.tsx | 28 + react-examples/Card/ListGroupWithHeader.tsx | 17 + react-examples/Card/ListGroups.tsx | 16 + react-examples/Card/NavPills.tsx | 34 + react-examples/Card/NavTabs.tsx | 34 + react-examples/Card/Text.tsx | 20 + react-examples/Card/WithHeader.tsx | 19 + react-examples/Card/WithHeaderAndQuote.tsx | 23 + react-examples/Card/WithHeaderStyled.tsx | 19 + react-examples/Carousel/CarouselFade.tsx | 34 + react-examples/Carousel/Controlled.tsx | 41 ++ react-examples/Carousel/DarkVariant.tsx | 45 ++ .../Carousel/IndividualIntervals.tsx | 34 + react-examples/Carousel/NoTransition.tsx | 34 + react-examples/Carousel/Uncontrolled.tsx | 34 + react-examples/CloseButton/Basic.tsx | 7 + react-examples/CloseButton/Disabled.tsx | 7 + react-examples/CloseButton/Labelled.tsx | 7 + react-examples/CloseButton/Variants.tsx | 12 + react-examples/Collapse.tsx | 28 + react-examples/CollapseHorizontal.tsx | 34 + react-examples/ColorMode.tsx | 42 ++ react-examples/CustomBreakpoints.tsx | 6 + react-examples/Dropdown/AutoClose.tsx | 57 ++ react-examples/Dropdown/Basic.tsx | 19 + react-examples/Dropdown/BasicButton.tsx | 14 + react-examples/Dropdown/ButtonCustom.tsx | 37 + react-examples/Dropdown/ButtonCustomMenu.tsx | 67 ++ react-examples/Dropdown/ButtonDark.tsx | 42 ++ react-examples/Dropdown/ButtonSizes.tsx | 48 ++ react-examples/Dropdown/DropDirections.tsx | 52 ++ react-examples/Dropdown/DropdownItemTags.tsx | 15 + react-examples/Dropdown/MenuAlignEnd.tsx | 20 + .../Dropdown/MenuAlignResponsive.tsx | 33 + react-examples/Dropdown/MenuDividers.tsx | 15 + react-examples/Dropdown/MenuHeaders.tsx | 13 + react-examples/Dropdown/NavbarDark.tsx | 36 + react-examples/Dropdown/SplitBasic.tsx | 21 + react-examples/Dropdown/SplitVariants.tsx | 29 + react-examples/Dropdown/Variants.tsx | 31 + react-examples/Fade.tsx | 28 + react-examples/Figure.tsx | 19 + react-examples/Form/Basic.tsx | 29 + react-examples/Form/Check.tsx | 26 + react-examples/Form/CheckApi.tsx | 21 + react-examples/Form/CheckInline.tsx | 35 + react-examples/Form/CheckReverse.tsx | 35 + react-examples/Form/ColorPicker.tsx | 17 + react-examples/Form/FormControlDisabled.tsx | 24 + react-examples/Form/FormDisabled.tsx | 31 + react-examples/Form/FormDisabledInputs.tsx | 23 + react-examples/Form/FormFile.tsx | 30 + react-examples/Form/FormFloatingBasic.tsx | 21 + react-examples/Form/FormFloatingCustom.tsx | 26 + react-examples/Form/FormFloatingLayout.tsx | 31 + react-examples/Form/FormFloatingSelect.tsx | 17 + react-examples/Form/FormFloatingTextarea.tsx | 25 + react-examples/Form/FormGroup.tsx | 18 + react-examples/Form/FormLabelSizing.tsx | 38 ++ react-examples/Form/FormText.tsx | 20 + react-examples/Form/GridAutoSizing.tsx | 48 ++ react-examples/Form/GridAutoSizingColMix.tsx | 44 ++ react-examples/Form/GridBasic.tsx | 20 + react-examples/Form/GridColSizes.tsx | 23 + react-examples/Form/GridComplex.tsx | 62 ++ react-examples/Form/Horizontal.tsx | 68 ++ react-examples/Form/InputReadOnly.tsx | 9 + react-examples/Form/InputSizes.tsx | 15 + react-examples/Form/NoLabels.tsx | 12 + react-examples/Form/Plaintext.tsx | 29 + react-examples/Form/Range.tsx | 12 + react-examples/Form/SelectBasic.tsx | 14 + react-examples/Form/SelectSizes.tsx | 21 + react-examples/Form/Switch.tsx | 21 + react-examples/Form/TextControls.tsx | 18 + react-examples/Form/ValidationFormik.tsx | 146 ++++ react-examples/Form/ValidationInputGroup.tsx | 16 + react-examples/Form/ValidationNative.tsx | 96 +++ react-examples/Form/ValidationTooltips.tsx | 187 +++++ react-examples/Grid/AutoLayout.tsx | 21 + react-examples/Grid/AutoLayoutSizing.tsx | 22 + react-examples/Grid/AutoLayoutVariable.tsx | 28 + react-examples/Grid/Container.tsx | 15 + react-examples/Grid/ContainerFluid.tsx | 15 + .../Grid/ContainerFluidBreakpoint.tsx | 15 + react-examples/Grid/Offsetting.tsx | 23 + react-examples/Grid/Ordering.tsx | 17 + react-examples/Grid/OrderingFirstLast.tsx | 17 + react-examples/Grid/Responsive.tsx | 40 ++ react-examples/Grid/ResponsiveAuto.tsx | 21 + react-examples/Grid/RowColLayout.tsx | 26 + .../Grid/RowColLayoutColWidthBreakpoint.tsx | 17 + react-examples/Image/Fluid.tsx | 7 + react-examples/Image/Shape.tsx | 24 + react-examples/InputGroup/Basic.tsx | 47 ++ react-examples/InputGroup/ButtonDropdowns.tsx | 71 ++ react-examples/InputGroup/Buttons.tsx | 47 ++ react-examples/InputGroup/Checkboxes.tsx | 19 + react-examples/InputGroup/MultipleAddons.tsx | 21 + react-examples/InputGroup/MultipleInputs.tsx | 14 + .../InputGroup/SegmentedButtonDropdowns.tsx | 43 ++ react-examples/InputGroup/Sizes.tsx | 36 + react-examples/ListGroup/Active.tsx | 18 + react-examples/ListGroup/Buttons.tsx | 19 + react-examples/ListGroup/Default.tsx | 15 + react-examples/ListGroup/Disabled.tsx | 14 + react-examples/ListGroup/Flush.tsx | 14 + react-examples/ListGroup/Header.tsx | 17 + react-examples/ListGroup/Horizontal.tsx | 14 + .../ListGroup/HorizontalResponsive.tsx | 18 + react-examples/ListGroup/Linked.tsx | 23 + react-examples/ListGroup/Numbered.tsx | 13 + react-examples/ListGroup/NumberedCustom.tsx | 47 ++ react-examples/ListGroup/Style.tsx | 19 + react-examples/ListGroup/StyleActions.tsx | 33 + react-examples/ListGroup/Tabs.tsx | 31 + react-examples/Modal/Basic.tsx | 35 + react-examples/Modal/CustomSizing.tsx | 41 ++ react-examples/Modal/DefaultSizing.tsx | 45 ++ react-examples/Modal/Focus.tsx | 54 ++ react-examples/Modal/FullScreen.tsx | 33 + react-examples/Modal/Grid.tsx | 61 ++ react-examples/Modal/Static.tsx | 28 + react-examples/Modal/StaticBackdrop.tsx | 41 ++ react-examples/Modal/VerticallyCentered.tsx | 49 ++ react-examples/Modal/WithoutAnimation.tsx | 35 + react-examples/Nav/Alignment.tsx | 43 ++ react-examples/Nav/Basic.tsx | 27 + react-examples/Nav/Dropdown.tsx | 35 + react-examples/Nav/DropdownImpl.tsx | 16 + react-examples/Nav/Fill.tsx | 24 + react-examples/Nav/Justified.tsx | 24 + react-examples/Nav/List.tsx | 19 + react-examples/Nav/Pills.tsx | 21 + react-examples/Nav/Stacked.tsx | 16 + react-examples/Nav/Tabs.tsx | 21 + react-examples/Nav/Underline.tsx | 21 + react-examples/Navbar/Basic.tsx | 34 + react-examples/Navbar/Brand.tsx | 51 ++ react-examples/Navbar/Collapsible.tsx | 40 ++ react-examples/Navbar/ColorSchemes.tsx | 45 ++ react-examples/Navbar/ContainerInside.tsx | 14 + react-examples/Navbar/ContainerOutside.tsx | 16 + react-examples/Navbar/Form.tsx | 39 ++ react-examples/Navbar/NavScroll.tsx | 51 ++ react-examples/Navbar/Offcanvas.tsx | 63 ++ react-examples/Navbar/TextLink.tsx | 20 + react-examples/Offcanvas/Backdrop.tsx | 62 ++ react-examples/Offcanvas/Basic.tsx | 30 + react-examples/Offcanvas/Placement.tsx | 39 ++ react-examples/Offcanvas/Responsive.tsx | 36 + react-examples/Offcanvas/StaticBackdrop.tsx | 29 + react-examples/Overlays/Disabled.tsx | 17 + react-examples/Overlays/Overlay.tsx | 42 ++ react-examples/Overlays/PopoverBasic.tsx | 21 + react-examples/Overlays/PopoverContained.tsx | 38 ++ react-examples/Overlays/PopoverPositioned.tsx | 29 + .../Overlays/PopoverPositionedScrolling.tsx | 61 ++ .../Overlays/PopoverTriggerBehaviors.tsx | 50 ++ react-examples/Overlays/ScheduleUpdate.tsx | 51 ++ react-examples/Overlays/TooltipInCopy.tsx | 37 + react-examples/Overlays/TooltipOverlay.tsx | 26 + react-examples/Overlays/TooltipPositioned.tsx | 25 + react-examples/Overlays/Trigger.tsx | 23 + react-examples/Overlays/TriggerRenderProp.tsx | 29 + react-examples/Pagination/Advanced.tsx | 25 + react-examples/Pagination/Basic.tsx | 25 + react-examples/Placeholder/Animation.tsx | 16 + react-examples/Placeholder/Card.tsx | 37 + react-examples/Placeholder/Color.tsx | 20 + react-examples/Placeholder/Example.tsx | 15 + react-examples/Placeholder/Size.tsx | 14 + react-examples/Placeholder/Width.tsx | 12 + react-examples/ProgressBar/Animated.tsx | 7 + react-examples/ProgressBar/Basic.tsx | 7 + react-examples/ProgressBar/Contextual.tsx | 14 + .../ProgressBar/ScreenreaderLabel.tsx | 8 + react-examples/ProgressBar/Stacked.tsx | 13 + react-examples/ProgressBar/Striped.tsx | 14 + react-examples/ProgressBar/WithLabel.tsx | 8 + react-examples/Ratio/Custom.tsx | 16 + react-examples/Ratio/Default.tsx | 15 + react-examples/Ratio/Example.tsx | 13 + react-examples/Spinner/Basic.tsx | 11 + react-examples/Spinner/Border.tsx | 7 + react-examples/Spinner/Buttons.tsx | 31 + react-examples/Spinner/Grow.tsx | 7 + react-examples/Spinner/Sizes.tsx | 14 + react-examples/Spinner/Variants.tsx | 26 + react-examples/Stack/Buttons.tsx | 13 + react-examples/Stack/Form.tsx | 16 + react-examples/Stack/Horizontal.tsx | 13 + .../Stack/HorizontalMarginStart.tsx | 13 + .../Stack/HorizontalVerticalRules.tsx | 14 + react-examples/Stack/Vertical.tsx | 13 + react-examples/Table/Basic.tsx | 37 + react-examples/Table/Dark.tsx | 37 + react-examples/Table/Responsive.tsx | 38 ++ .../Table/ResponsiveBreakpoints.tsx | 178 +++++ react-examples/Table/Small.tsx | 37 + react-examples/Table/StripedColumns.tsx | 37 + react-examples/Table/StripedRow.tsx | 37 + react-examples/Tabs/Controlled.tsx | 28 + react-examples/Tabs/Fill.tsx | 28 + react-examples/Tabs/Justified.tsx | 28 + react-examples/Tabs/LeftTabs.tsx | 31 + react-examples/Tabs/NoAnimation.tsx | 25 + react-examples/Tabs/Uncontrolled.tsx | 24 + react-examples/Theming/Prefixes.tsx | 18 + react-examples/Theming/Variants.tsx | 27 + react-examples/Toast/Autohide.tsx | 33 + react-examples/Toast/Basic.tsx | 16 + react-examples/Toast/Contextual.tsx | 39 ++ react-examples/Toast/Dismissible.tsx | 54 ++ react-examples/Toast/Placement.tsx | 65 ++ react-examples/Toast/PlacementMulti.tsx | 42 ++ react-examples/Toast/Stacking.tsx | 27 + react/AbstractModalHeader.tsx | 82 +++ react/Accordion.tsx | 105 +++ react/AccordionBody.tsx | 93 +++ react/AccordionButton.tsx | 108 +++ react/AccordionCollapse.tsx | 65 ++ react/AccordionContext.ts | 28 + react/AccordionHeader.tsx | 56 ++ react/AccordionItem.tsx | 67 ++ react/AccordionItemContext.ts | 12 + react/Alert.tsx | 141 ++++ react/AlertHeading.tsx | 30 + react/AlertLink.tsx | 27 + react/Anchor.tsx | 5 + react/Badge.tsx | 79 +++ react/BootstrapModalManager.tsx | 91 +++ react/Breadcrumb.tsx | 76 +++ react/BreadcrumbItem.tsx | 103 +++ react/Button.tsx | 121 ++++ react/ButtonGroup.tsx | 79 +++ react/ButtonToolbar.tsx | 45 ++ react/Card.tsx | 115 ++++ react/CardBody.tsx | 26 + react/CardFooter.tsx | 26 + react/CardGroup.tsx | 26 + react/CardHeader.tsx | 58 ++ react/CardHeaderContext.tsx | 10 + react/CardImg.tsx | 61 ++ react/CardImgOverlay.tsx | 28 + react/CardLink.tsx | 26 + react/CardSubtitle.tsx | 29 + react/CardText.tsx | 26 + react/CardTitle.tsx | 29 + react/Carousel.tsx | 641 ++++++++++++++++++ react/CarouselCaption.tsx | 28 + react/CarouselItem.tsx | 47 ++ react/CloseButton.tsx | 49 ++ react/Col.tsx | 196 ++++++ react/Collapse.tsx | 258 +++++++ react/Container.tsx | 62 ++ react/Dropdown.tsx | 231 +++++++ react/DropdownButton.tsx | 144 ++++ react/DropdownContext.ts | 21 + react/DropdownDivider.tsx | 32 + react/DropdownHeader.tsx | 32 + react/DropdownItem.tsx | 91 +++ react/DropdownItemText.tsx | 28 + react/DropdownMenu.tsx | 231 +++++++ react/DropdownToggle.tsx | 98 +++ react/ElementChildren.tsx | 51 ++ react/Fade.tsx | 148 ++++ react/Feedback.tsx | 59 ++ react/Figure.tsx | 31 + react/FigureCaption.tsx | 28 + react/FigureImage.tsx | 20 + react/FloatingLabel.tsx | 50 ++ react/Form.tsx | 75 ++ react/FormCheck.tsx | 222 ++++++ react/FormCheckInput.tsx | 86 +++ react/FormCheckLabel.tsx | 44 ++ react/FormContext.tsx | 10 + react/FormControl.tsx | 158 +++++ react/FormFloating.tsx | 26 + react/FormGroup.tsx | 57 ++ react/FormLabel.tsx | 123 ++++ react/FormRange.tsx | 62 ++ react/FormSelect.tsx | 100 +++ react/FormText.tsx | 60 ++ react/Image.tsx | 76 +++ react/InputGroup.tsx | 97 +++ react/InputGroupContext.tsx | 6 + react/InputGroupText.tsx | 28 + react/ListGroup.tsx | 101 +++ react/ListGroupItem.tsx | 134 ++++ react/Modal.tsx | 520 ++++++++++++++ react/ModalBody.tsx | 26 + react/ModalContext.tsx | 12 + react/ModalDialog.tsx | 104 +++ react/ModalFooter.tsx | 26 + react/ModalHeader.tsx | 73 ++ react/ModalTitle.tsx | 29 + react/Nav.tsx | 167 +++++ react/NavContext.tsx | 14 + react/NavDropdown.tsx | 124 ++++ react/NavItem.tsx | 26 + react/NavLink.tsx | 99 +++ react/Navbar.tsx | 219 ++++++ react/NavbarBrand.tsx | 49 ++ react/NavbarCollapse.tsx | 38 ++ react/NavbarContext.tsx | 14 + react/NavbarOffcanvas.tsx | 32 + react/NavbarText.tsx | 26 + react/NavbarToggle.tsx | 82 +++ react/Offcanvas.tsx | 353 ++++++++++ react/OffcanvasBody.tsx | 26 + react/OffcanvasHeader.tsx | 73 ++ react/OffcanvasTitle.tsx | 31 + react/OffcanvasToggling.tsx | 138 ++++ react/Overlay.tsx | 258 +++++++ react/OverlayTrigger.tsx | 324 +++++++++ react/PageItem.tsx | 106 +++ react/Pagination.tsx | 58 ++ react/Placeholder.tsx | 51 ++ react/PlaceholderButton.tsx | 45 ++ react/Popover.tsx | 147 ++++ react/PopoverBody.tsx | 26 + react/PopoverHeader.tsx | 26 + react/ProgressBar.tsx | 237 +++++++ react/Ratio.tsx | 73 ++ react/Row.tsx | 158 +++++ react/SSRProvider.ts | 6 + react/Spinner.tsx | 96 +++ react/SplitButton.tsx | 164 +++++ react/Stack.tsx | 79 +++ react/Switch.tsx | 17 + react/Tab.tsx | 53 ++ react/TabContainer.tsx | 77 +++ react/TabContent.tsx | 26 + react/TabPane.tsx | 161 +++++ react/Table.tsx | 119 ++++ react/Tabs.tsx | 184 +++++ react/ThemeProvider.tsx | 120 ++++ react/Toast.tsx | 207 ++++++ react/ToastBody.tsx | 26 + react/ToastContainer.tsx | 100 +++ react/ToastContext.tsx | 12 + react/ToastFade.tsx | 19 + react/ToastHeader.tsx | 82 +++ react/ToggleButton.tsx | 128 ++++ react/ToggleButtonGroup.tsx | 146 ++++ react/Tooltip.tsx | 133 ++++ react/TransitionWrapper.tsx | 93 +++ react/createChainedFunction.tsx | 31 + react/createUtilityClasses.ts | 52 ++ react/createWithBsPrefix.tsx | 49 ++ react/divWithClassName.tsx | 11 + react/getInitialPopperStyles.ts | 11 + react/getTabTransitionComponent.ts | 14 + react/helpers.ts | 59 ++ react/index.tsx | 334 +++++++++ react/safeFindDOMNode.ts | 10 + react/transitionEndListener.ts | 29 + react/triggerBrowserReflow.tsx | 6 + react/types.tsx | 74 ++ react/useOverlayOffset.tsx | 43 ++ react/usePlaceholder.ts | 34 + react/useWrappedRefWithWarning.tsx | 22 + ui/Anchor.tsx | 47 ++ ui/Button.tsx | 148 ++++ ui/DataKey.tsx | 11 + ui/Dropdown.tsx | 360 ++++++++++ ui/DropdownContext.ts | 17 + ui/DropdownItem.tsx | 119 ++++ ui/DropdownMenu.tsx | 229 +++++++ ui/DropdownToggle.tsx | 104 +++ ui/ImperativeTransition.tsx | 134 ++++ ui/Modal.tsx | 493 ++++++++++++++ ui/ModalManager.ts | 153 +++++ ui/Nav.tsx | 178 +++++ ui/NavContext.tsx | 14 + ui/NavItem.tsx | 138 ++++ ui/NoopTransition.tsx | 40 ++ ui/Overlay.tsx | 231 +++++++ ui/Portal.tsx | 34 + ui/RTGTransition.tsx | 19 + ui/SelectableContext.tsx | 14 + ui/TabContext.tsx | 16 + ui/TabPanel.tsx | 174 +++++ ui/Tabs.tsx | 122 ++++ ui/Waypoint.tsx | 47 ++ ui/getScrollbarWidth.ts | 10 + ui/index.ts | 46 ++ ui/mergeOptionsWithPopperConfig.ts | 91 +++ ui/popper.ts | 27 + ui/ssr.tsx | 10 + ui/types.ts | 108 +++ ui/useClickOutside.ts | 158 +++++ ui/usePopper.ts | 231 +++++++ ui/useRTGTransitionProps.ts | 87 +++ ui/useRootClose.ts | 69 ++ ui/useScrollParent.tsx | 17 + ui/useWaitForDOMRef.ts | 54 ++ ui/useWaypoint.tsx | 148 ++++ ui/useWindow.ts | 16 + ui/utils.ts | 14 + uncontrollable/index.ts | 92 +++ warning/warning.d.ts | 2 + warning/warning.ts | 62 ++ 590 files changed, 29411 insertions(+), 13 deletions(-) create mode 100644 dequal/alts.ts create mode 100644 dequal/index.ts create mode 100644 dequal/lite.ts create mode 100644 design-tokens-cli/chooseTransform.ts create mode 100644 design-tokens-cli/example/tokens-layout/inset.tokens.json create mode 100644 design-tokens-cli/example/tokens-layout/size.tokens.json create mode 100644 design-tokens-cli/example/tokens-type/color.tokens create mode 100644 design-tokens-cli/example/tokens-type/font-size.tokens.json create mode 100644 design-tokens-cli/example/tokens.config.json create mode 100644 design-tokens-cli/filterByGroup.ts create mode 100644 design-tokens-cli/findDuplicates.ts create mode 100644 design-tokens-cli/findTrueValues.ts create mode 100644 design-tokens-cli/flattenJSON.ts create mode 100755 design-tokens-cli/index.ts create mode 100644 design-tokens-cli/refToName.ts create mode 100644 design-tokens-cli/sortKeys.ts create mode 100644 design-tokens-cli/tests/filterByGroup.test.ts create mode 100644 design-tokens-cli/tests/findTrueValues.test.ts create mode 100644 design-tokens-cli/tests/refToName.test.ts create mode 100644 design-tokens-cli/tests/sortKeys.test.ts create mode 100644 design-tokens-cli/tests/toCustomProps.test.ts create mode 100644 design-tokens-cli/tests/toESM.test.ts create mode 100644 design-tokens-cli/tests/toJSON.test.ts create mode 100644 design-tokens-cli/tests/toScssVars.test.ts create mode 100644 design-tokens-cli/transform.ts create mode 100644 design-tokens-cli/transformers/toCustomProps.ts create mode 100644 design-tokens-cli/transformers/toESM.ts create mode 100644 design-tokens-cli/transformers/toJSON.ts create mode 100644 design-tokens-cli/transformers/toScssVars.ts create mode 100644 dom-helpers/activeElement.ts create mode 100644 dom-helpers/addClass.ts create mode 100644 dom-helpers/addEventListener.ts create mode 100644 dom-helpers/animate.ts create mode 100644 dom-helpers/animationFrame.ts create mode 100644 dom-helpers/attribute.ts create mode 100644 dom-helpers/camelize.ts create mode 100644 dom-helpers/camelizeStyle.ts create mode 100644 dom-helpers/canUseDOM.ts create mode 100644 dom-helpers/childElements.ts create mode 100644 dom-helpers/childNodes.ts create mode 100644 dom-helpers/clear.ts create mode 100644 dom-helpers/closest.ts create mode 100644 dom-helpers/collectElements.ts create mode 100644 dom-helpers/collectSiblings.ts create mode 100644 dom-helpers/contains.ts create mode 100644 dom-helpers/css.ts create mode 100644 dom-helpers/filterEventHandler.ts create mode 100644 dom-helpers/getComputedStyle.ts create mode 100644 dom-helpers/getScrollAccessor.ts create mode 100644 dom-helpers/hasClass.ts create mode 100644 dom-helpers/height.ts create mode 100644 dom-helpers/hyphenate.ts create mode 100644 dom-helpers/hyphenateStyle.ts create mode 100644 dom-helpers/index.ts create mode 100644 dom-helpers/insertAfter.ts create mode 100644 dom-helpers/isDocument.ts create mode 100644 dom-helpers/isInput.ts create mode 100644 dom-helpers/isTransform.ts create mode 100644 dom-helpers/isVisible.ts create mode 100644 dom-helpers/isWindow.ts create mode 100644 dom-helpers/listen.ts create mode 100644 dom-helpers/matches.ts create mode 100644 dom-helpers/nextUntil.ts create mode 100644 dom-helpers/offset.ts create mode 100644 dom-helpers/offsetParent.ts create mode 100644 dom-helpers/ownerDocument.ts create mode 100644 dom-helpers/ownerWindow.ts create mode 100644 dom-helpers/parents.ts create mode 100644 dom-helpers/position.ts create mode 100644 dom-helpers/prepend.ts create mode 100644 dom-helpers/querySelectorAll.ts create mode 100644 dom-helpers/remove.ts create mode 100644 dom-helpers/removeClass.ts create mode 100644 dom-helpers/removeEventListener.ts create mode 100644 dom-helpers/scrollLeft.ts create mode 100644 dom-helpers/scrollParent.ts create mode 100644 dom-helpers/scrollTo.ts create mode 100644 dom-helpers/scrollTop.ts create mode 100644 dom-helpers/scrollbarSize.ts create mode 100644 dom-helpers/siblings.ts create mode 100644 dom-helpers/text.ts create mode 100644 dom-helpers/toggleClass.ts create mode 100644 dom-helpers/transitionEnd.ts create mode 100644 dom-helpers/triggerEvent.ts create mode 100644 dom-helpers/types.d.ts create mode 100644 dom-helpers/width.ts create mode 100644 hooks/globals.d.ts create mode 100644 hooks/index.ts create mode 100644 hooks/useAnimationFrame.ts create mode 100644 hooks/useBreakpoint.ts create mode 100644 hooks/useCallbackRef.ts create mode 100644 hooks/useCommittedRef.ts create mode 100644 hooks/useCustomEffect.ts create mode 100644 hooks/useDebouncedCallback.ts create mode 100644 hooks/useDebouncedState.ts create mode 100644 hooks/useDebouncedValue.ts create mode 100644 hooks/useEventCallback.ts create mode 100644 hooks/useEventListener.ts create mode 100644 hooks/useFocusManager.ts create mode 100644 hooks/useForceUpdate.ts create mode 100644 hooks/useGlobalListener.ts create mode 100644 hooks/useImage.ts create mode 100644 hooks/useImmediateUpdateEffect.ts create mode 100644 hooks/useIntersectionObserver.ts create mode 100644 hooks/useInterval.ts create mode 100644 hooks/useIsInitialRenderRef.ts create mode 100644 hooks/useIsomorphicEffect.ts create mode 100644 hooks/useMap.ts create mode 100644 hooks/useMediaQuery.tsx create mode 100644 hooks/useMergeState.ts create mode 100644 hooks/useMergeStateFromProps.ts create mode 100644 hooks/useMergedRefs.ts create mode 100644 hooks/useMountEffect.ts create mode 100644 hooks/useMounted.ts create mode 100644 hooks/useMutationObserver.ts create mode 100644 hooks/usePrevious.ts create mode 100644 hooks/useRafInterval.ts create mode 100644 hooks/useRefWithInitialValueFactory.ts create mode 100644 hooks/useResizeObserver.ts create mode 100644 hooks/useSafeState.ts create mode 100644 hooks/useSet.ts create mode 100644 hooks/useStableMemo.ts create mode 100644 hooks/useStateAsync.ts create mode 100644 hooks/useThrottledEventHandler.ts create mode 100644 hooks/useTimeout.ts create mode 100644 hooks/useToggleState.ts create mode 100644 hooks/useUpdateEffect.ts create mode 100644 hooks/useUpdateImmediateEffect.ts create mode 100644 hooks/useUpdateLayoutEffect.ts create mode 100644 hooks/useUpdatedRef.ts create mode 100644 hooks/useWillUnmount.ts create mode 100644 invariant/index.ts create mode 100644 prop-types-extra/all.ts create mode 100644 prop-types-extra/componentOrElement.ts create mode 100644 prop-types-extra/deprecated.ts create mode 100644 prop-types-extra/elementType.ts create mode 100644 prop-types-extra/index.ts create mode 100644 prop-types-extra/isRequiredForA11y.ts create mode 100644 prop-types-extra/utils/createChainableTypeChecker.ts create mode 100644 react-examples/Accordion/AllCollapse.tsx create mode 100644 react-examples/Accordion/AlwaysOpen.tsx create mode 100644 react-examples/Accordion/Basic.tsx create mode 100644 react-examples/Accordion/ContextAwareToggle.tsx create mode 100644 react-examples/Accordion/CustomToggle.tsx create mode 100644 react-examples/Accordion/Flush.tsx create mode 100644 react-examples/Alert/AdditionalContent.tsx create mode 100644 react-examples/Alert/Basic.tsx create mode 100644 react-examples/Alert/Dismissible.tsx create mode 100644 react-examples/Alert/DismissibleControlled.tsx create mode 100644 react-examples/Alert/Link.tsx create mode 100644 react-examples/AsProp.tsx create mode 100644 react-examples/AsPropComponent.tsx create mode 100644 react-examples/Badge/Basic.tsx create mode 100644 react-examples/Badge/Button.tsx create mode 100644 react-examples/Badge/Pill.tsx create mode 100644 react-examples/Badge/Variations.tsx create mode 100644 react-examples/Breadcrumb.tsx create mode 100644 react-examples/Button/Active.tsx create mode 100644 react-examples/Button/Block.tsx create mode 100644 react-examples/Button/Disabled.tsx create mode 100644 react-examples/Button/Loading.tsx create mode 100644 react-examples/Button/OutlineTypes.tsx create mode 100644 react-examples/Button/Sizes.tsx create mode 100644 react-examples/Button/TagTypes.tsx create mode 100644 react-examples/Button/ToggleButton.tsx create mode 100644 react-examples/Button/ToggleButtonGroupControlled.tsx create mode 100644 react-examples/Button/ToggleButtonGroupUncontrolled.tsx create mode 100644 react-examples/Button/Types.tsx create mode 100644 react-examples/ButtonGroup/Basic.tsx create mode 100644 react-examples/ButtonGroup/Nested.tsx create mode 100644 react-examples/ButtonGroup/Sizes.tsx create mode 100644 react-examples/ButtonGroup/Toolbar.tsx create mode 100644 react-examples/ButtonGroup/ToolbarBasic.tsx create mode 100644 react-examples/ButtonGroup/Vertical.tsx create mode 100644 react-examples/Card/Basic.tsx create mode 100644 react-examples/Card/BgColor.tsx create mode 100644 react-examples/Card/BodyOnly.tsx create mode 100644 react-examples/Card/BodyShorthand.tsx create mode 100644 react-examples/Card/Border.tsx create mode 100644 react-examples/Card/Grid.tsx create mode 100644 react-examples/Card/Group.tsx create mode 100644 react-examples/Card/HeaderAndFooter.tsx create mode 100644 react-examples/Card/ImageAndText.tsx create mode 100644 react-examples/Card/ImgOverlay.tsx create mode 100644 react-examples/Card/KitchenSink.tsx create mode 100644 react-examples/Card/ListGroupWithHeader.tsx create mode 100644 react-examples/Card/ListGroups.tsx create mode 100644 react-examples/Card/NavPills.tsx create mode 100644 react-examples/Card/NavTabs.tsx create mode 100644 react-examples/Card/Text.tsx create mode 100644 react-examples/Card/WithHeader.tsx create mode 100644 react-examples/Card/WithHeaderAndQuote.tsx create mode 100644 react-examples/Card/WithHeaderStyled.tsx create mode 100644 react-examples/Carousel/CarouselFade.tsx create mode 100644 react-examples/Carousel/Controlled.tsx create mode 100644 react-examples/Carousel/DarkVariant.tsx create mode 100644 react-examples/Carousel/IndividualIntervals.tsx create mode 100644 react-examples/Carousel/NoTransition.tsx create mode 100644 react-examples/Carousel/Uncontrolled.tsx create mode 100644 react-examples/CloseButton/Basic.tsx create mode 100644 react-examples/CloseButton/Disabled.tsx create mode 100644 react-examples/CloseButton/Labelled.tsx create mode 100644 react-examples/CloseButton/Variants.tsx create mode 100644 react-examples/Collapse.tsx create mode 100644 react-examples/CollapseHorizontal.tsx create mode 100644 react-examples/ColorMode.tsx create mode 100644 react-examples/CustomBreakpoints.tsx create mode 100644 react-examples/Dropdown/AutoClose.tsx create mode 100644 react-examples/Dropdown/Basic.tsx create mode 100644 react-examples/Dropdown/BasicButton.tsx create mode 100644 react-examples/Dropdown/ButtonCustom.tsx create mode 100644 react-examples/Dropdown/ButtonCustomMenu.tsx create mode 100644 react-examples/Dropdown/ButtonDark.tsx create mode 100644 react-examples/Dropdown/ButtonSizes.tsx create mode 100644 react-examples/Dropdown/DropDirections.tsx create mode 100644 react-examples/Dropdown/DropdownItemTags.tsx create mode 100644 react-examples/Dropdown/MenuAlignEnd.tsx create mode 100644 react-examples/Dropdown/MenuAlignResponsive.tsx create mode 100644 react-examples/Dropdown/MenuDividers.tsx create mode 100644 react-examples/Dropdown/MenuHeaders.tsx create mode 100644 react-examples/Dropdown/NavbarDark.tsx create mode 100644 react-examples/Dropdown/SplitBasic.tsx create mode 100644 react-examples/Dropdown/SplitVariants.tsx create mode 100644 react-examples/Dropdown/Variants.tsx create mode 100644 react-examples/Fade.tsx create mode 100644 react-examples/Figure.tsx create mode 100644 react-examples/Form/Basic.tsx create mode 100644 react-examples/Form/Check.tsx create mode 100644 react-examples/Form/CheckApi.tsx create mode 100644 react-examples/Form/CheckInline.tsx create mode 100644 react-examples/Form/CheckReverse.tsx create mode 100644 react-examples/Form/ColorPicker.tsx create mode 100644 react-examples/Form/FormControlDisabled.tsx create mode 100644 react-examples/Form/FormDisabled.tsx create mode 100644 react-examples/Form/FormDisabledInputs.tsx create mode 100644 react-examples/Form/FormFile.tsx create mode 100644 react-examples/Form/FormFloatingBasic.tsx create mode 100644 react-examples/Form/FormFloatingCustom.tsx create mode 100644 react-examples/Form/FormFloatingLayout.tsx create mode 100644 react-examples/Form/FormFloatingSelect.tsx create mode 100644 react-examples/Form/FormFloatingTextarea.tsx create mode 100644 react-examples/Form/FormGroup.tsx create mode 100644 react-examples/Form/FormLabelSizing.tsx create mode 100644 react-examples/Form/FormText.tsx create mode 100644 react-examples/Form/GridAutoSizing.tsx create mode 100644 react-examples/Form/GridAutoSizingColMix.tsx create mode 100644 react-examples/Form/GridBasic.tsx create mode 100644 react-examples/Form/GridColSizes.tsx create mode 100644 react-examples/Form/GridComplex.tsx create mode 100644 react-examples/Form/Horizontal.tsx create mode 100644 react-examples/Form/InputReadOnly.tsx create mode 100644 react-examples/Form/InputSizes.tsx create mode 100644 react-examples/Form/NoLabels.tsx create mode 100644 react-examples/Form/Plaintext.tsx create mode 100644 react-examples/Form/Range.tsx create mode 100644 react-examples/Form/SelectBasic.tsx create mode 100644 react-examples/Form/SelectSizes.tsx create mode 100644 react-examples/Form/Switch.tsx create mode 100644 react-examples/Form/TextControls.tsx create mode 100644 react-examples/Form/ValidationFormik.tsx create mode 100644 react-examples/Form/ValidationInputGroup.tsx create mode 100644 react-examples/Form/ValidationNative.tsx create mode 100644 react-examples/Form/ValidationTooltips.tsx create mode 100644 react-examples/Grid/AutoLayout.tsx create mode 100644 react-examples/Grid/AutoLayoutSizing.tsx create mode 100644 react-examples/Grid/AutoLayoutVariable.tsx create mode 100644 react-examples/Grid/Container.tsx create mode 100644 react-examples/Grid/ContainerFluid.tsx create mode 100644 react-examples/Grid/ContainerFluidBreakpoint.tsx create mode 100644 react-examples/Grid/Offsetting.tsx create mode 100644 react-examples/Grid/Ordering.tsx create mode 100644 react-examples/Grid/OrderingFirstLast.tsx create mode 100644 react-examples/Grid/Responsive.tsx create mode 100644 react-examples/Grid/ResponsiveAuto.tsx create mode 100644 react-examples/Grid/RowColLayout.tsx create mode 100644 react-examples/Grid/RowColLayoutColWidthBreakpoint.tsx create mode 100644 react-examples/Image/Fluid.tsx create mode 100644 react-examples/Image/Shape.tsx create mode 100644 react-examples/InputGroup/Basic.tsx create mode 100644 react-examples/InputGroup/ButtonDropdowns.tsx create mode 100644 react-examples/InputGroup/Buttons.tsx create mode 100644 react-examples/InputGroup/Checkboxes.tsx create mode 100644 react-examples/InputGroup/MultipleAddons.tsx create mode 100644 react-examples/InputGroup/MultipleInputs.tsx create mode 100644 react-examples/InputGroup/SegmentedButtonDropdowns.tsx create mode 100644 react-examples/InputGroup/Sizes.tsx create mode 100644 react-examples/ListGroup/Active.tsx create mode 100644 react-examples/ListGroup/Buttons.tsx create mode 100644 react-examples/ListGroup/Default.tsx create mode 100644 react-examples/ListGroup/Disabled.tsx create mode 100644 react-examples/ListGroup/Flush.tsx create mode 100644 react-examples/ListGroup/Header.tsx create mode 100644 react-examples/ListGroup/Horizontal.tsx create mode 100644 react-examples/ListGroup/HorizontalResponsive.tsx create mode 100644 react-examples/ListGroup/Linked.tsx create mode 100644 react-examples/ListGroup/Numbered.tsx create mode 100644 react-examples/ListGroup/NumberedCustom.tsx create mode 100644 react-examples/ListGroup/Style.tsx create mode 100644 react-examples/ListGroup/StyleActions.tsx create mode 100644 react-examples/ListGroup/Tabs.tsx create mode 100644 react-examples/Modal/Basic.tsx create mode 100644 react-examples/Modal/CustomSizing.tsx create mode 100644 react-examples/Modal/DefaultSizing.tsx create mode 100644 react-examples/Modal/Focus.tsx create mode 100644 react-examples/Modal/FullScreen.tsx create mode 100644 react-examples/Modal/Grid.tsx create mode 100644 react-examples/Modal/Static.tsx create mode 100644 react-examples/Modal/StaticBackdrop.tsx create mode 100644 react-examples/Modal/VerticallyCentered.tsx create mode 100644 react-examples/Modal/WithoutAnimation.tsx create mode 100644 react-examples/Nav/Alignment.tsx create mode 100644 react-examples/Nav/Basic.tsx create mode 100644 react-examples/Nav/Dropdown.tsx create mode 100644 react-examples/Nav/DropdownImpl.tsx create mode 100644 react-examples/Nav/Fill.tsx create mode 100644 react-examples/Nav/Justified.tsx create mode 100644 react-examples/Nav/List.tsx create mode 100644 react-examples/Nav/Pills.tsx create mode 100644 react-examples/Nav/Stacked.tsx create mode 100644 react-examples/Nav/Tabs.tsx create mode 100644 react-examples/Nav/Underline.tsx create mode 100644 react-examples/Navbar/Basic.tsx create mode 100644 react-examples/Navbar/Brand.tsx create mode 100644 react-examples/Navbar/Collapsible.tsx create mode 100644 react-examples/Navbar/ColorSchemes.tsx create mode 100644 react-examples/Navbar/ContainerInside.tsx create mode 100644 react-examples/Navbar/ContainerOutside.tsx create mode 100644 react-examples/Navbar/Form.tsx create mode 100644 react-examples/Navbar/NavScroll.tsx create mode 100644 react-examples/Navbar/Offcanvas.tsx create mode 100644 react-examples/Navbar/TextLink.tsx create mode 100644 react-examples/Offcanvas/Backdrop.tsx create mode 100644 react-examples/Offcanvas/Basic.tsx create mode 100644 react-examples/Offcanvas/Placement.tsx create mode 100644 react-examples/Offcanvas/Responsive.tsx create mode 100644 react-examples/Offcanvas/StaticBackdrop.tsx create mode 100644 react-examples/Overlays/Disabled.tsx create mode 100644 react-examples/Overlays/Overlay.tsx create mode 100644 react-examples/Overlays/PopoverBasic.tsx create mode 100644 react-examples/Overlays/PopoverContained.tsx create mode 100644 react-examples/Overlays/PopoverPositioned.tsx create mode 100644 react-examples/Overlays/PopoverPositionedScrolling.tsx create mode 100644 react-examples/Overlays/PopoverTriggerBehaviors.tsx create mode 100644 react-examples/Overlays/ScheduleUpdate.tsx create mode 100644 react-examples/Overlays/TooltipInCopy.tsx create mode 100644 react-examples/Overlays/TooltipOverlay.tsx create mode 100644 react-examples/Overlays/TooltipPositioned.tsx create mode 100644 react-examples/Overlays/Trigger.tsx create mode 100644 react-examples/Overlays/TriggerRenderProp.tsx create mode 100644 react-examples/Pagination/Advanced.tsx create mode 100644 react-examples/Pagination/Basic.tsx create mode 100644 react-examples/Placeholder/Animation.tsx create mode 100644 react-examples/Placeholder/Card.tsx create mode 100644 react-examples/Placeholder/Color.tsx create mode 100644 react-examples/Placeholder/Example.tsx create mode 100644 react-examples/Placeholder/Size.tsx create mode 100644 react-examples/Placeholder/Width.tsx create mode 100644 react-examples/ProgressBar/Animated.tsx create mode 100644 react-examples/ProgressBar/Basic.tsx create mode 100644 react-examples/ProgressBar/Contextual.tsx create mode 100644 react-examples/ProgressBar/ScreenreaderLabel.tsx create mode 100644 react-examples/ProgressBar/Stacked.tsx create mode 100644 react-examples/ProgressBar/Striped.tsx create mode 100644 react-examples/ProgressBar/WithLabel.tsx create mode 100644 react-examples/Ratio/Custom.tsx create mode 100644 react-examples/Ratio/Default.tsx create mode 100644 react-examples/Ratio/Example.tsx create mode 100644 react-examples/Spinner/Basic.tsx create mode 100644 react-examples/Spinner/Border.tsx create mode 100644 react-examples/Spinner/Buttons.tsx create mode 100644 react-examples/Spinner/Grow.tsx create mode 100644 react-examples/Spinner/Sizes.tsx create mode 100644 react-examples/Spinner/Variants.tsx create mode 100644 react-examples/Stack/Buttons.tsx create mode 100644 react-examples/Stack/Form.tsx create mode 100644 react-examples/Stack/Horizontal.tsx create mode 100644 react-examples/Stack/HorizontalMarginStart.tsx create mode 100644 react-examples/Stack/HorizontalVerticalRules.tsx create mode 100644 react-examples/Stack/Vertical.tsx create mode 100644 react-examples/Table/Basic.tsx create mode 100644 react-examples/Table/Dark.tsx create mode 100644 react-examples/Table/Responsive.tsx create mode 100644 react-examples/Table/ResponsiveBreakpoints.tsx create mode 100644 react-examples/Table/Small.tsx create mode 100644 react-examples/Table/StripedColumns.tsx create mode 100644 react-examples/Table/StripedRow.tsx create mode 100644 react-examples/Tabs/Controlled.tsx create mode 100644 react-examples/Tabs/Fill.tsx create mode 100644 react-examples/Tabs/Justified.tsx create mode 100644 react-examples/Tabs/LeftTabs.tsx create mode 100644 react-examples/Tabs/NoAnimation.tsx create mode 100644 react-examples/Tabs/Uncontrolled.tsx create mode 100644 react-examples/Theming/Prefixes.tsx create mode 100644 react-examples/Theming/Variants.tsx create mode 100644 react-examples/Toast/Autohide.tsx create mode 100644 react-examples/Toast/Basic.tsx create mode 100644 react-examples/Toast/Contextual.tsx create mode 100644 react-examples/Toast/Dismissible.tsx create mode 100644 react-examples/Toast/Placement.tsx create mode 100644 react-examples/Toast/PlacementMulti.tsx create mode 100644 react-examples/Toast/Stacking.tsx create mode 100644 react/AbstractModalHeader.tsx create mode 100644 react/Accordion.tsx create mode 100644 react/AccordionBody.tsx create mode 100644 react/AccordionButton.tsx create mode 100644 react/AccordionCollapse.tsx create mode 100644 react/AccordionContext.ts create mode 100644 react/AccordionHeader.tsx create mode 100644 react/AccordionItem.tsx create mode 100644 react/AccordionItemContext.ts create mode 100644 react/Alert.tsx create mode 100644 react/AlertHeading.tsx create mode 100644 react/AlertLink.tsx create mode 100644 react/Anchor.tsx create mode 100644 react/Badge.tsx create mode 100644 react/BootstrapModalManager.tsx create mode 100644 react/Breadcrumb.tsx create mode 100644 react/BreadcrumbItem.tsx create mode 100644 react/Button.tsx create mode 100644 react/ButtonGroup.tsx create mode 100644 react/ButtonToolbar.tsx create mode 100644 react/Card.tsx create mode 100644 react/CardBody.tsx create mode 100644 react/CardFooter.tsx create mode 100644 react/CardGroup.tsx create mode 100644 react/CardHeader.tsx create mode 100644 react/CardHeaderContext.tsx create mode 100644 react/CardImg.tsx create mode 100644 react/CardImgOverlay.tsx create mode 100644 react/CardLink.tsx create mode 100644 react/CardSubtitle.tsx create mode 100644 react/CardText.tsx create mode 100644 react/CardTitle.tsx create mode 100644 react/Carousel.tsx create mode 100644 react/CarouselCaption.tsx create mode 100644 react/CarouselItem.tsx create mode 100644 react/CloseButton.tsx create mode 100644 react/Col.tsx create mode 100644 react/Collapse.tsx create mode 100644 react/Container.tsx create mode 100644 react/Dropdown.tsx create mode 100644 react/DropdownButton.tsx create mode 100644 react/DropdownContext.ts create mode 100644 react/DropdownDivider.tsx create mode 100644 react/DropdownHeader.tsx create mode 100644 react/DropdownItem.tsx create mode 100644 react/DropdownItemText.tsx create mode 100644 react/DropdownMenu.tsx create mode 100644 react/DropdownToggle.tsx create mode 100644 react/ElementChildren.tsx create mode 100644 react/Fade.tsx create mode 100644 react/Feedback.tsx create mode 100644 react/Figure.tsx create mode 100644 react/FigureCaption.tsx create mode 100644 react/FigureImage.tsx create mode 100644 react/FloatingLabel.tsx create mode 100644 react/Form.tsx create mode 100644 react/FormCheck.tsx create mode 100644 react/FormCheckInput.tsx create mode 100644 react/FormCheckLabel.tsx create mode 100644 react/FormContext.tsx create mode 100644 react/FormControl.tsx create mode 100644 react/FormFloating.tsx create mode 100644 react/FormGroup.tsx create mode 100644 react/FormLabel.tsx create mode 100644 react/FormRange.tsx create mode 100644 react/FormSelect.tsx create mode 100644 react/FormText.tsx create mode 100644 react/Image.tsx create mode 100644 react/InputGroup.tsx create mode 100644 react/InputGroupContext.tsx create mode 100644 react/InputGroupText.tsx create mode 100644 react/ListGroup.tsx create mode 100644 react/ListGroupItem.tsx create mode 100644 react/Modal.tsx create mode 100644 react/ModalBody.tsx create mode 100644 react/ModalContext.tsx create mode 100644 react/ModalDialog.tsx create mode 100644 react/ModalFooter.tsx create mode 100644 react/ModalHeader.tsx create mode 100644 react/ModalTitle.tsx create mode 100644 react/Nav.tsx create mode 100644 react/NavContext.tsx create mode 100644 react/NavDropdown.tsx create mode 100644 react/NavItem.tsx create mode 100644 react/NavLink.tsx create mode 100644 react/Navbar.tsx create mode 100644 react/NavbarBrand.tsx create mode 100644 react/NavbarCollapse.tsx create mode 100644 react/NavbarContext.tsx create mode 100644 react/NavbarOffcanvas.tsx create mode 100644 react/NavbarText.tsx create mode 100644 react/NavbarToggle.tsx create mode 100644 react/Offcanvas.tsx create mode 100644 react/OffcanvasBody.tsx create mode 100644 react/OffcanvasHeader.tsx create mode 100644 react/OffcanvasTitle.tsx create mode 100644 react/OffcanvasToggling.tsx create mode 100644 react/Overlay.tsx create mode 100644 react/OverlayTrigger.tsx create mode 100644 react/PageItem.tsx create mode 100644 react/Pagination.tsx create mode 100644 react/Placeholder.tsx create mode 100644 react/PlaceholderButton.tsx create mode 100644 react/Popover.tsx create mode 100644 react/PopoverBody.tsx create mode 100644 react/PopoverHeader.tsx create mode 100644 react/ProgressBar.tsx create mode 100644 react/Ratio.tsx create mode 100644 react/Row.tsx create mode 100644 react/SSRProvider.ts create mode 100644 react/Spinner.tsx create mode 100644 react/SplitButton.tsx create mode 100644 react/Stack.tsx create mode 100644 react/Switch.tsx create mode 100644 react/Tab.tsx create mode 100644 react/TabContainer.tsx create mode 100644 react/TabContent.tsx create mode 100644 react/TabPane.tsx create mode 100644 react/Table.tsx create mode 100644 react/Tabs.tsx create mode 100644 react/ThemeProvider.tsx create mode 100644 react/Toast.tsx create mode 100644 react/ToastBody.tsx create mode 100644 react/ToastContainer.tsx create mode 100644 react/ToastContext.tsx create mode 100644 react/ToastFade.tsx create mode 100644 react/ToastHeader.tsx create mode 100644 react/ToggleButton.tsx create mode 100644 react/ToggleButtonGroup.tsx create mode 100644 react/Tooltip.tsx create mode 100644 react/TransitionWrapper.tsx create mode 100644 react/createChainedFunction.tsx create mode 100644 react/createUtilityClasses.ts create mode 100644 react/createWithBsPrefix.tsx create mode 100644 react/divWithClassName.tsx create mode 100644 react/getInitialPopperStyles.ts create mode 100644 react/getTabTransitionComponent.ts create mode 100644 react/helpers.ts create mode 100644 react/index.tsx create mode 100644 react/safeFindDOMNode.ts create mode 100644 react/transitionEndListener.ts create mode 100644 react/triggerBrowserReflow.tsx create mode 100644 react/types.tsx create mode 100644 react/useOverlayOffset.tsx create mode 100644 react/usePlaceholder.ts create mode 100644 react/useWrappedRefWithWarning.tsx create mode 100644 ui/Anchor.tsx create mode 100644 ui/Button.tsx create mode 100644 ui/DataKey.tsx create mode 100644 ui/Dropdown.tsx create mode 100644 ui/DropdownContext.ts create mode 100644 ui/DropdownItem.tsx create mode 100644 ui/DropdownMenu.tsx create mode 100644 ui/DropdownToggle.tsx create mode 100644 ui/ImperativeTransition.tsx create mode 100644 ui/Modal.tsx create mode 100644 ui/ModalManager.ts create mode 100644 ui/Nav.tsx create mode 100644 ui/NavContext.tsx create mode 100644 ui/NavItem.tsx create mode 100644 ui/NoopTransition.tsx create mode 100644 ui/Overlay.tsx create mode 100644 ui/Portal.tsx create mode 100644 ui/RTGTransition.tsx create mode 100644 ui/SelectableContext.tsx create mode 100644 ui/TabContext.tsx create mode 100644 ui/TabPanel.tsx create mode 100644 ui/Tabs.tsx create mode 100644 ui/Waypoint.tsx create mode 100644 ui/getScrollbarWidth.ts create mode 100644 ui/index.ts create mode 100644 ui/mergeOptionsWithPopperConfig.ts create mode 100644 ui/popper.ts create mode 100644 ui/ssr.tsx create mode 100644 ui/types.ts create mode 100644 ui/useClickOutside.ts create mode 100644 ui/usePopper.ts create mode 100644 ui/useRTGTransitionProps.ts create mode 100644 ui/useRootClose.ts create mode 100644 ui/useScrollParent.tsx create mode 100644 ui/useWaitForDOMRef.ts create mode 100644 ui/useWaypoint.tsx create mode 100644 ui/useWindow.ts create mode 100644 ui/utils.ts create mode 100644 uncontrollable/index.ts create mode 100644 warning/warning.d.ts create mode 100644 warning/warning.ts diff --git a/dequal/alts.ts b/dequal/alts.ts new file mode 100644 index 0000000..8c6c054 --- /dev/null +++ b/dequal/alts.ts @@ -0,0 +1,78 @@ +// 227B – 128k op/s +export function v227(foo, bar) { + var keys, ctor; + return foo === bar || ( + foo && bar && (ctor=foo.constructor) === bar.constructor ? + ctor === RegExp ? foo.toString() == bar.toString() + : ctor === Date ? foo.getTime() == bar.getTime() + : ctor === Array ? + foo.length === bar.length && foo.every(function (val, idx) { + return v227(val, bar[idx]); + }) + : ctor === Object + && (keys=Object.keys(foo)).length === Object.keys(bar).length + && keys.every(function (k) { + return k in bar && v227(foo[k], bar[k]); + }) + : (foo !== foo && bar !== bar) + ); +} + +// 255B – 155k op/s +export function v255(foo, bar) { + var ctor, len, k; + if (foo === bar) return true; + if (foo && bar && (ctor=foo.constructor) === bar.constructor) { + if (ctor === Date) return foo.getTime() === bar.getTime(); + if (ctor === RegExp) return foo.toString() === bar.toString(); + if (ctor === Array && (len=foo.length) === bar.length) { + while (len-- > 0 && v255(foo[len], bar[len])); + return len === -1; + } + if (ctor === Object) { + if (Object.keys(foo).length !== Object.keys(bar).length) return false; + for (k in foo) { + if (!(k in bar) || !v255(foo[k], bar[k])) return false; + } + return true; + } + } + return foo !== foo && bar !== bar; +} + +// 246B – 157k op/s +export function v246(foo, bar) { + var ctor, i; + if (foo === bar) return true; + if (foo && bar && (ctor=foo.constructor) === bar.constructor) { + if (ctor === Date) return foo.getTime() === bar.getTime(); + if (ctor === RegExp) return foo.toString() === bar.toString(); + if (ctor === Array) { + if (foo.length !== bar.length) return false; + for (i=0; i < foo.length; i++) if (!v246(foo[i], bar[i])) return false; + return true + } + if (ctor === Object) { + if (Object.keys(foo).length !== Object.keys(bar).length) return false; + for (i in foo) if (!(i in bar) || !v246(foo[i], bar[i])) return false; + return true; + } + } + return foo !== foo && bar !== bar; +} + +// 225B - 97k op/s +export function v225(foo, bar) { + var ctor, keys, len; + if (foo === bar) return true; + if (foo && bar && (ctor=foo.constructor) === bar.constructor) { + if (ctor === Date) return foo.getTime() === bar.getTime(); + if (ctor === RegExp) return foo.toString() === bar.toString(); + if (typeof foo === 'object') { + if (Object.keys(foo).length !== Object.keys(bar).length) return false; + for (len in foo) if (!(len in bar) || !v225(foo[len], bar[len])) return false; + return true; + } + } + return foo !== foo && bar !== bar; +} diff --git a/dequal/index.ts b/dequal/index.ts new file mode 100644 index 0000000..d0b1e2d --- /dev/null +++ b/dequal/index.ts @@ -0,0 +1,84 @@ +var has = Object.prototype.hasOwnProperty; + +function find(iter, tar, key) { + for (key of iter.keys()) { + if (dequal(key, tar)) return key; + } +} + +export function dequal(foo, bar) { + var ctor, len, tmp; + if (foo === bar) return true; + + if (foo && bar && (ctor=foo.constructor) === bar.constructor) { + if (ctor === Date) return foo.getTime() === bar.getTime(); + if (ctor === RegExp) return foo.toString() === bar.toString(); + + if (ctor === Array) { + if ((len=foo.length) === bar.length) { + while (len-- && dequal(foo[len], bar[len])); + } + return len === -1; + } + + if (ctor === Set) { + if (foo.size !== bar.size) { + return false; + } + for (len of foo) { + tmp = len; + if (tmp && typeof tmp === 'object') { + tmp = find(bar, tmp); + if (!tmp) return false; + } + if (!bar.has(tmp)) return false; + } + return true; + } + + if (ctor === Map) { + if (foo.size !== bar.size) { + return false; + } + for (len of foo) { + tmp = len[0]; + if (tmp && typeof tmp === 'object') { + tmp = find(bar, tmp); + if (!tmp) return false; + } + if (!dequal(len[1], bar.get(tmp))) { + return false; + } + } + return true; + } + + if (ctor === ArrayBuffer) { + foo = new Uint8Array(foo); + bar = new Uint8Array(bar); + } else if (ctor === DataView) { + if ((len=foo.byteLength) === bar.byteLength) { + while (len-- && foo.getInt8(len) === bar.getInt8(len)); + } + return len === -1; + } + + if (ArrayBuffer.isView(foo)) { + if ((len=foo.byteLength) === bar.byteLength) { + while (len-- && foo[len] === bar[len]); + } + return len === -1; + } + + if (!ctor || typeof foo === 'object') { + len = 0; + for (ctor in foo) { + if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false; + if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false; + } + return Object.keys(bar).length === len; + } + } + + return foo !== foo && bar !== bar; +} diff --git a/dequal/lite.ts b/dequal/lite.ts new file mode 100644 index 0000000..5820d67 --- /dev/null +++ b/dequal/lite.ts @@ -0,0 +1,29 @@ +var has = Object.prototype.hasOwnProperty; + +export function dequal(foo, bar) { + var ctor, len; + if (foo === bar) return true; + + if (foo && bar && (ctor=foo.constructor) === bar.constructor) { + if (ctor === Date) return foo.getTime() === bar.getTime(); + if (ctor === RegExp) return foo.toString() === bar.toString(); + + if (ctor === Array) { + if ((len=foo.length) === bar.length) { + while (len-- && dequal(foo[len], bar[len])); + } + return len === -1; + } + + if (!ctor || typeof foo === 'object') { + len = 0; + for (ctor in foo) { + if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false; + if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false; + } + return Object.keys(bar).length === len; + } + } + + return foo !== foo && bar !== bar; +} diff --git a/design-tokens-cli/chooseTransform.ts b/design-tokens-cli/chooseTransform.ts new file mode 100644 index 0000000..221084a --- /dev/null +++ b/design-tokens-cli/chooseTransform.ts @@ -0,0 +1,27 @@ +import { toCustomProps } from './transformers/toCustomProps.js'; +import { toScssVars } from './transformers/toScssVars.js'; +import { toESM } from './transformers/toESM.js'; +import { toJSON } from './transformers/toJSON.js'; + +/** + * Convert an object of design token name/value pairs into Scss (Sass) variables + * @param {Object} pairs The flattened token key/value pairs + * @param {String} as What the tokens should be transformed into + * @returns {String} + */ + const chooseTransform = (pairs, as, groupName, config) => { + switch (as) { + case 'css': + return toCustomProps(pairs, config); + case 'scss': + return toScssVars(pairs, config); + case 'mjs' || 'js': + return toESM(pairs, groupName, config); + case 'json': + return toJSON(pairs, config); + default: + throw new Error(`The 'as' value ${as} is not recognized.`); + } +} + +export { chooseTransform } \ No newline at end of file diff --git a/design-tokens-cli/example/tokens-layout/inset.tokens.json b/design-tokens-cli/example/tokens-layout/inset.tokens.json new file mode 100644 index 0000000..f0159c7 --- /dev/null +++ b/design-tokens-cli/example/tokens-layout/inset.tokens.json @@ -0,0 +1,20 @@ +{ + "inset": { + "a": { + "$value": { + "left": "0", + "top": "0", + "bottom": "0", + "right": "0" + } + }, + "b": { + "$value": { + "left": "50%", + "top": "50%", + "bottom": "50%", + "right": "50%" + } + } + } +} \ No newline at end of file diff --git a/design-tokens-cli/example/tokens-layout/size.tokens.json b/design-tokens-cli/example/tokens-layout/size.tokens.json new file mode 100644 index 0000000..9ab9fb6 --- /dev/null +++ b/design-tokens-cli/example/tokens-layout/size.tokens.json @@ -0,0 +1,88 @@ +{ + "sizing": { + "relative": { + "0": { + "$value": "0", + "comment": "no spacing, zero." + }, + "25": { + "$value": ".0625", + "comment": ".0625rem, 1px" + }, + "50": { + "$value": ".125rem", + "comment": ".125rem, 2px" + }, + "100": { + "$value": ".25rem", + "comment": ".25rem, 4px." + }, + "200": { + "$value": ".5rem", + "comment": ".5rem, 8px." + }, + "400": { + "$value": "1rem", + "comment": "1rem, 16px." + }, + "600": { + "$value": "1.5rem", + "comment": "1.5rem, 24px." + }, + "800": { + "$value": "2rem", + "comment": "2rem, 32px." + }, + "1200": { + "$value": "3rem", + "comment": "3rem, 48px." + }, + "1600": { + "$value": "4rem", + "comment": "4rem, 64px." + } + }, + "absolute": { + "0": { + "$value": "0", + "comment": "no spacing, zero." + }, + "25": { + "$value": "1px", + "comment": ".0625rem, 1px" + }, + "50": { + "$value": "2px", + "comment": ".125rem, 2px" + }, + "100": { + "$value": "4px", + "comment": ".25rem, 4px." + }, + "200": { + "$value": "8px", + "comment": ".5rem, 8px." + }, + "400": { + "$value": "16px", + "comment": "1rem, 16px." + }, + "600": { + "$value": "24px", + "comment": "1.5rem, 24px." + }, + "800": { + "$value": "32px", + "comment": "2rem, 32px." + }, + "1200": { + "$value": "48px", + "comment": "3rem, 48px." + }, + "1600": { + "$value": "64px", + "comment": "4rem, 64px." + } + } + } +} \ No newline at end of file diff --git a/design-tokens-cli/example/tokens-type/color.tokens b/design-tokens-cli/example/tokens-type/color.tokens new file mode 100644 index 0000000..95b697c --- /dev/null +++ b/design-tokens-cli/example/tokens-type/color.tokens @@ -0,0 +1,50 @@ +{ + "color": { + "white": { + "name": "white", + "$value": "#ffffff" + }, + "blanche": { + "name": "white", + "$value": "{color.white}" + }, + "weiss": { + "name": "white", + "$value": "{color.blanche}" + }, + "black": { + "name": "black", + "$value": "#000000" + }, + "grayscale": { + "200": { + "name": "grayscale-200", + "$value": "#f8f8f8" + }, + "300": { + "name": "grayscale-300", + "$value": "#f3f3f3" + }, + "400": { + "name": "grayscale-400", + "$value": "#dadada" + }, + "500": { + "name": "grayscale-500", + "$value": "#999999" + }, + "600": { + "name": "grayscale-600", + "$value": "#666666" + }, + "700": { + "name": "grayscale-700", + "$value": "#555555" + }, + "800": { + "name": "grayscale-800", + "$value": "#222222" + } + } + } +} \ No newline at end of file diff --git a/design-tokens-cli/example/tokens-type/font-size.tokens.json b/design-tokens-cli/example/tokens-type/font-size.tokens.json new file mode 100644 index 0000000..ebdf973 --- /dev/null +++ b/design-tokens-cli/example/tokens-type/font-size.tokens.json @@ -0,0 +1,40 @@ +{ + "font-size": { + "350": { + "$value": ".875rem", + "comment": "14px" + }, + "400": { + "$value": "1rem", + "comment": "16px" + }, + "450": { + "$value": "1.125rem", + "comment": "18px" + }, + "500": { + "$value": "1.25rem", + "comment": "20px" + }, + "600": { + "$value": "1.5rem", + "comment": "24px" + }, + "650": { + "$value": "1.875rem", + "comment": "28px" + }, + "800": { + "$value": "2rem", + "comment": "32px" + }, + "875": { + "$value": "2.1875rem", + "comment": "35px" + }, + "900": { + "$value": "2.5rem", + "comment": "36px" + } + } +} \ No newline at end of file diff --git a/design-tokens-cli/example/tokens.config.json b/design-tokens-cli/example/tokens.config.json new file mode 100644 index 0000000..4833c2d --- /dev/null +++ b/design-tokens-cli/example/tokens.config.json @@ -0,0 +1,48 @@ +{ + "globalPrefix": "token", + "transforms": [ + { + "name": "layout", + "from": "example/tokens-layout", + "to": [ + { + "as": "scss", + "to": "example/output/scss" + }, + { + "as": "css", + "to": "example/output/css" + }, + { + "as": "mjs", + "to": "example/output/js" + }, + { + "as": "json", + "to": "example/output/json" + } + ] + }, + { + "from": "example/tokens-type", + "to": [ + { + "as": "scss", + "to": "example/output/scss" + }, + { + "as": "css", + "to": "example/output/css" + }, + { + "as": "mjs", + "to": "example/output/js" + }, + { + "as": "json", + "to": "example/output/json" + } + ] + } + ] +} \ No newline at end of file diff --git a/design-tokens-cli/filterByGroup.ts b/design-tokens-cli/filterByGroup.ts new file mode 100644 index 0000000..70c13f7 --- /dev/null +++ b/design-tokens-cli/filterByGroup.ts @@ -0,0 +1,17 @@ +/** + * Filter an object of token key/values by the group name + * @param {Object} tokens The starting object (one level of key/value pairs only) + * @returns {Object} + */ +const filterByGroup = (tokens, groupName) => { + let filtered = Object.keys(tokens) + .filter(key => key.startsWith(groupName)) + .reduce((obj, key) => { + return Object.assign(obj, { + [key]: tokens[key] + }); + }, {}); + return filtered; +} + +export { filterByGroup } \ No newline at end of file diff --git a/design-tokens-cli/findDuplicates.ts b/design-tokens-cli/findDuplicates.ts new file mode 100644 index 0000000..28771b0 --- /dev/null +++ b/design-tokens-cli/findDuplicates.ts @@ -0,0 +1,10 @@ +/** + * Finds duplicates in an array + * @param {Array} arr The starting array + * @returns {Array} + */ +const findDuplicates = arr => { + return arr.filter((item, index) => arr.indexOf(item) !== index); +} + +export { findDuplicates } \ No newline at end of file diff --git a/design-tokens-cli/findTrueValues.ts b/design-tokens-cli/findTrueValues.ts new file mode 100644 index 0000000..13bca97 --- /dev/null +++ b/design-tokens-cli/findTrueValues.ts @@ -0,0 +1,28 @@ +import { refToName } from "./refToName.js"; + +/** + * Searches through chained references to replace reference with originating value + * @param {Object} pairs The flattened token key/value pairs + * @returns {Object} + */ +const findTrueValues = groups => { + const newGroups = JSON.parse(JSON.stringify(groups)); + let justPairs = {}; + Object.keys(newGroups).forEach(group => { + Object.assign(justPairs, newGroups[group]); + }); + for (const pair in justPairs) { + let val = justPairs[pair]; + while (val.startsWith('{')) { + let name = refToName(justPairs[pair]); + if (!justPairs[name]) { + throw new Error(`The token reference name '${name}' does not exist.`); + } + val = justPairs[name]; + } + justPairs[pair] = val; + } + return justPairs; +} + +export { findTrueValues } diff --git a/design-tokens-cli/flattenJSON.ts b/design-tokens-cli/flattenJSON.ts new file mode 100644 index 0000000..5d52788 --- /dev/null +++ b/design-tokens-cli/flattenJSON.ts @@ -0,0 +1,54 @@ +import { sortKeys } from './sortKeys.js'; + +/** + * Create a simple object of design token name/value pairs from sped-adhering design tokens JSON + * @param {Array} tokens A standard design tokens object (JSON)) + * @returns {Object} of token names and values + */ +const flattenJSON = tokens => { + const existingObjects = []; + const path = []; + const tokensArrays = []; + (function find(tokens) { + for (const key of Object.keys(tokens)) { + if (key === '$value') { + if (typeof tokens[key] === 'string') { + path.push(tokens[key]); + tokensArrays.push([...path]); + path.pop(); + } else if (typeof tokens[key] === 'object') { + let $values = tokens[key]; + for (const key in $values) { + let pathCopy = [...path]; + pathCopy.push(key); + pathCopy.push($values[key]); + tokensArrays.push([...pathCopy]); + } + } else { + throw new Error(`$value properties must be strings or objects.`); + } + } + const o = tokens[key]; + if (o && typeof o === "object" && !Array.isArray(o)) { + if (!existingObjects.find(tokens => tokens === o)) { + path.push(key); + existingObjects.push(o); + find(o); + path.pop(); + } + } + } + }(tokens)); + const newObject = {}; + tokensArrays.forEach(arr => { + const keys = arr.slice(0, -1).map(k => { + return k.split(' ').join('-'); + }); + const key = keys.join('-'); + const value = arr.at(-1); + newObject[key] = value; + }); + return sortKeys(newObject); +} + +export { flattenJSON } \ No newline at end of file diff --git a/design-tokens-cli/index.ts b/design-tokens-cli/index.ts new file mode 100755 index 0000000..365ee6d --- /dev/null +++ b/design-tokens-cli/index.ts @@ -0,0 +1,17 @@ +#!/usr/bin/env node + +import { program as cli } from 'commander'; +import { transform } from './utils/transform.js'; + +cli.description('Process spec-conforming design tokens JSON'); +cli.name('designTokens'); +cli.usage(""); +cli.addHelpCommand(false); +cli.helpOption(false); + +cli + .command('transform') + .argument('[configPath]', 'The config file path') + .action(transform); + +cli.parse(process.argv); \ No newline at end of file diff --git a/design-tokens-cli/refToName.ts b/design-tokens-cli/refToName.ts new file mode 100644 index 0000000..d80db4c --- /dev/null +++ b/design-tokens-cli/refToName.ts @@ -0,0 +1,12 @@ +/** + * Convert design token references to design token names + * @param {String} refString The design tokens reference $value + * @returns {String} A design token name (kebab case) + */ +const refToName = refString => { + const cropped = refString.slice(1,-1).trim(); + const kebabbed = cropped.split('.').join('-').split(' ').join('-'); + return kebabbed; +} + +export { refToName } \ No newline at end of file diff --git a/design-tokens-cli/sortKeys.ts b/design-tokens-cli/sortKeys.ts new file mode 100644 index 0000000..8509446 --- /dev/null +++ b/design-tokens-cli/sortKeys.ts @@ -0,0 +1,14 @@ +/** + * Sort a shallow object alphabetically by key + * @param {Object} object A shallow object to be sorted alphabetically, by key + * @returns {Object} + */ +const sortKeys = object => { + return Object.keys(object) + .sort() + .reduce((acc, key) => ({ + ...acc, [key]: object[key] + }), {}); +} + +export { sortKeys } \ No newline at end of file diff --git a/design-tokens-cli/tests/filterByGroup.test.ts b/design-tokens-cli/tests/filterByGroup.test.ts new file mode 100644 index 0000000..aea9ac2 --- /dev/null +++ b/design-tokens-cli/tests/filterByGroup.test.ts @@ -0,0 +1,14 @@ +'use strict'; +import { filterByGroup } from '../utils/filterByGroup.js'; + +test('Filters tokens key/value pairs by group name', () => { + const tokens = { + "color-token-1": "#000", + "color-token-2": "#fff", + "size-token-1": "1em", + "size-token-2": "2em" + } + + const filtered = filterByGroup(tokens, 'color'); + expect(Object.keys(filtered).length).toEqual(2); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/findTrueValues.test.ts b/design-tokens-cli/tests/findTrueValues.test.ts new file mode 100644 index 0000000..af405d8 --- /dev/null +++ b/design-tokens-cli/tests/findTrueValues.test.ts @@ -0,0 +1,15 @@ +'use strict'; +import { findTrueValues } from '../utils/findTrueValues.js'; + +test('Searches through references to find true value and apply it', () => { + const tokens = { + 'color': { + 'color-white': '#ffffff', + 'color-blanche': '{color.white}', + 'color-weiss': '{color.blanche}' + } + } + + const resolved = findTrueValues(tokens); + expect(resolved['color-weiss']).toBe('#ffffff'); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/refToName.test.ts b/design-tokens-cli/tests/refToName.test.ts new file mode 100644 index 0000000..fa76071 --- /dev/null +++ b/design-tokens-cli/tests/refToName.test.ts @@ -0,0 +1,9 @@ +'use strict'; +import { refToName } from "../utils/refToName.js"; + +test('Converts a reference string to a real token name.', () => { + const ref = '{ color.gray scale.0 }'; + + const converted = refToName(ref); + expect(converted).toBe('color-gray-scale-0'); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/sortKeys.test.ts b/design-tokens-cli/tests/sortKeys.test.ts new file mode 100644 index 0000000..9a7f4bc --- /dev/null +++ b/design-tokens-cli/tests/sortKeys.test.ts @@ -0,0 +1,14 @@ +'use strict'; +import { sortKeys } from "../utils/sortKeys.js"; + +test('Sorts an object\'s keys alphabetically', () => { + const object = { + b: true, + c: true, + z: true, + a: true + } + + const sorted = sortKeys(object); + expect(Object.keys(sorted)[0]).toBe('a'); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/toCustomProps.test.ts b/design-tokens-cli/tests/toCustomProps.test.ts new file mode 100644 index 0000000..0c8a27a --- /dev/null +++ b/design-tokens-cli/tests/toCustomProps.test.ts @@ -0,0 +1,19 @@ +'use strict'; +import { toCustomProps } from "../utils/transformers/toCustomProps.js"; + +test('Converts tokens to CSS custom properties', () => { + const tokens = { + 'token-color-1': '#000', + 'token-color-2': '#fff' + } + + const expectedString = ` + :root { + --token-color-1: #000; + --token-color-2: #fff; + } + `; + + const returnedString = toCustomProps(tokens); + expect(expectedString.replace(/\s/g, '')).toEqual(returnedString.replace(/\s/g, '')); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/toESM.test.ts b/design-tokens-cli/tests/toESM.test.ts new file mode 100644 index 0000000..7318e7e --- /dev/null +++ b/design-tokens-cli/tests/toESM.test.ts @@ -0,0 +1,21 @@ +'use strict'; +import { toESM } from "../utils/transformers/toESM.js"; + +test('Converts tokens to ES modules', () => { + const tokens = { + 'token-color-1': '#000', + 'token-color-2': '#fff' + } + + const groupName = 'my-colors'; + + const expectedString = ` + export const myColors = { + 'token-color-1': '#000', + 'token-color-2': '#fff' + } + `; + + const returnedString = toESM(tokens, groupName); + expect(expectedString.replace(/\s/g, '')).toEqual(returnedString.replace(/\s/g, '')); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/toJSON.test.ts b/design-tokens-cli/tests/toJSON.test.ts new file mode 100644 index 0000000..0d1bc5c --- /dev/null +++ b/design-tokens-cli/tests/toJSON.test.ts @@ -0,0 +1,19 @@ +'use strict'; +import { toJSON } from "../utils/transformers/toJSON.js"; + +test('Converts tokens to (flat) JSON', () => { + const tokens = { + "token-color-1": "#000", + "token-color-2": "#fff" + } + + const expectedString = ` + { + "token-color-1": "#000", + "token-color-2": "#fff" + } + `; + + const returnedString = toJSON(tokens); + expect(expectedString.replace(/\s/g, '')).toEqual(returnedString.replace(/\s/g, '')); +}); \ No newline at end of file diff --git a/design-tokens-cli/tests/toScssVars.test.ts b/design-tokens-cli/tests/toScssVars.test.ts new file mode 100644 index 0000000..6a18f03 --- /dev/null +++ b/design-tokens-cli/tests/toScssVars.test.ts @@ -0,0 +1,17 @@ +'use strict'; +import { toScssVars } from "../utils/transformers/toScssVars.js"; + +test('Converts tokens to CSS Sass (scss) variables', () => { + const tokens = { + 'token-color-1': '#000', + 'token-color-2': '#fff' + } + + const expectedString = ` + $token-color-1: #000; + $token-color-2: #fff; + `; + + const returnedString = toScssVars(tokens); + expect(expectedString.replace(/\s/g, '')).toEqual(returnedString.replace(/\s/g, '')); +}); \ No newline at end of file diff --git a/design-tokens-cli/transform.ts b/design-tokens-cli/transform.ts new file mode 100644 index 0000000..f4f1a08 --- /dev/null +++ b/design-tokens-cli/transform.ts @@ -0,0 +1,67 @@ +import jetpack from 'fs-jetpack'; +import { findDuplicates } from "./findDuplicates.js"; +import { findTrueValues } from "./findTrueValues.js"; +import { flattenJSON } from './flattenJSON.js'; +import { chooseTransform } from './chooseTransform.js'; + +const transform = (configPath, options) => { + // If no config path argument, look for config file + if (!configPath) { + configPath = jetpack.find('./', { matching: 'tokens.config.json' })[0]; + } + if (!configPath) { + throw new Error('No config file found in current working directory.'); + } + + // Read the config file as JSON + const config = jetpack.read(configPath, 'json'); + + config.transforms.forEach(transform => { + let from = jetpack.cwd(transform.from); + // Keep track of tokens in one object + let allTokens = {}; + from.find({ matching: ['*.tokens.json', '*.tokens'] }).forEach(path => { + const json = from.read(path, 'json'); + let pairs = flattenJSON(json); + allTokens[path.split('.')[0]] = pairs; + }); + + // Resolve token references + const resolvedPairs = findTrueValues(allTokens); + // Exit if there are duplicate token names + const duplicates = findDuplicates(Object.keys(resolvedPairs)); + if (duplicates.length) { + throw new Error(`You have duplicate token names: ${duplicates.join(', ')}`); + } + + // Place true values back into categorized object + for (let group in allTokens) { + Object.keys(allTokens[group]).forEach(token => { + allTokens[group][token] = resolvedPairs[token]; + }); + } + + // If the transform has a name, concatenate under name + if (transform.name) { + transform.to.forEach(format => { + let code = chooseTransform(resolvedPairs, format.as, transform.name, config); + let formatTo = jetpack.cwd(format.to); + let newPath = `${transform.name}.tokens.${format.as}`; + formatTo.write(newPath, code); + }); + return; + // Otherwise, create separate files after file names + } else { + for (let group in allTokens) { + transform.to.forEach(format => { + let code = chooseTransform(allTokens[group], format.as, group, config); + let formatTo = jetpack.cwd(format.to); + let newPath = `${group}.tokens.${format.as}`; + formatTo.write(newPath, code); + }); + } + } + }); +} + +export { transform } \ No newline at end of file diff --git a/design-tokens-cli/transformers/toCustomProps.ts b/design-tokens-cli/transformers/toCustomProps.ts new file mode 100644 index 0000000..b91eafe --- /dev/null +++ b/design-tokens-cli/transformers/toCustomProps.ts @@ -0,0 +1,18 @@ +/** + * Convert an object of design token name/value pairs into CSS custom Properties + * @param {Object} tokensObject + * @returns {String} + */ +const toCustomProps = (tokensObject, config, includeRoot = true) => { + const prefix = config.globalPrefix ? `${config.globalPrefix}-` : ''; + let string = ''; + if (includeRoot) string += ':root {\n'; + Object.keys(tokensObject).forEach(key => { + if (includeRoot) string += ' '; + string += `\t--${prefix}${key}: ${tokensObject[key]};\n`; + }); + if (includeRoot) string += '}\n'; + return string; +} + +export { toCustomProps } \ No newline at end of file diff --git a/design-tokens-cli/transformers/toESM.ts b/design-tokens-cli/transformers/toESM.ts new file mode 100644 index 0000000..215c7c2 --- /dev/null +++ b/design-tokens-cli/transformers/toESM.ts @@ -0,0 +1,20 @@ +/** + * Convert an object of design token name/value pairs into an ES module + * @param {Object} tokensObject + * @returns {String} + */ +const toESM = (tokensObject, groupName, config) => { + const prefix = config.globalPrefix ? `${config.globalPrefix}-` : ''; + groupName = groupName.replace(/-./g, x=>x[1].toUpperCase()); + const keys = Object.keys(tokensObject); + let string = ''; + string += `export const ${groupName} = {\n`; + keys.forEach(key => { + let comma = (keys.indexOf(key) + 1) === keys.length ? '' : ','; + string += `\t'${prefix}${key}': '${tokensObject[key]}'${comma}\n`; + }); + string += `}`; + return string; +} + +export { toESM } \ No newline at end of file diff --git a/design-tokens-cli/transformers/toJSON.ts b/design-tokens-cli/transformers/toJSON.ts new file mode 100644 index 0000000..f66909c --- /dev/null +++ b/design-tokens-cli/transformers/toJSON.ts @@ -0,0 +1,15 @@ +/** + * Convert an object of design token name/value pairs into JSON (pass through, basically) + * @param {Object} tokensObject + * @returns {String} + */ + const toJSON = (tokensObject, config) => { + if (config.globalPrefix) { + tokensObject = Object.fromEntries( + Object.entries(tokensObject).map(([k, v]) => [`${config.globalPrefix}-${k}`, v]) + ) + } + return JSON.stringify(tokensObject, undefined, '\t'); +} + +export { toJSON } \ No newline at end of file diff --git a/design-tokens-cli/transformers/toScssVars.ts b/design-tokens-cli/transformers/toScssVars.ts new file mode 100644 index 0000000..4d3e7ea --- /dev/null +++ b/design-tokens-cli/transformers/toScssVars.ts @@ -0,0 +1,15 @@ +/** + * Convert an object of design token name/value pairs into Scss (Sass) variables + * @param {Object} tokensObject + * @returns {String} + */ +const toScssVars = (tokensObject, config) => { + const prefix = config.globalPrefix ? `${config.globalPrefix}-` : ''; + let string = ''; + Object.keys(tokensObject).forEach(key => { + string += `$${prefix}${key}: ${tokensObject[key]};\n`; + }); + return string; +} + +export { toScssVars } \ No newline at end of file diff --git a/dom-helpers/activeElement.ts b/dom-helpers/activeElement.ts new file mode 100644 index 0000000..6a90b1a --- /dev/null +++ b/dom-helpers/activeElement.ts @@ -0,0 +1,21 @@ +import ownerDocument from './ownerDocument' + +/** + * Returns the actively focused element safely. + * + * @param doc the document to check + */ +export default function activeElement(doc = ownerDocument()) { + // Support: IE 9 only + // IE9 throws an "Unspecified error" accessing document.activeElement from an