react-native-terra-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -0
- package/lib/module/components/avatar/Avatar.js +121 -0
- package/lib/module/components/avatar/Avatar.js.map +1 -0
- package/lib/module/components/avatar/index.js +4 -0
- package/lib/module/components/avatar/index.js.map +1 -0
- package/lib/module/components/avatar/types.js +4 -0
- package/lib/module/components/avatar/types.js.map +1 -0
- package/lib/module/components/box/Box.js +49 -0
- package/lib/module/components/box/Box.js.map +1 -0
- package/lib/module/components/box/index.js +4 -0
- package/lib/module/components/box/index.js.map +1 -0
- package/lib/module/components/box/utils.js +95 -0
- package/lib/module/components/box/utils.js.map +1 -0
- package/lib/module/components/button/Button.js +281 -0
- package/lib/module/components/button/Button.js.map +1 -0
- package/lib/module/components/button/index.js +4 -0
- package/lib/module/components/button/index.js.map +1 -0
- package/lib/module/components/header/Header.js +25 -0
- package/lib/module/components/header/Header.js.map +1 -0
- package/lib/module/components/header/header-buttons.js +65 -0
- package/lib/module/components/header/header-buttons.js.map +1 -0
- package/lib/module/components/header/index.js +7 -0
- package/lib/module/components/header/index.js.map +1 -0
- package/lib/module/components/header/variants/LargeTitleHeader/index.js +335 -0
- package/lib/module/components/header/variants/LargeTitleHeader/index.js.map +1 -0
- package/lib/module/components/header/variants/TitleHeader/index.js +184 -0
- package/lib/module/components/header/variants/TitleHeader/index.js.map +1 -0
- package/lib/module/components/icon/Icon.js +53 -0
- package/lib/module/components/icon/Icon.js.map +1 -0
- package/lib/module/components/icon/index.js +4 -0
- package/lib/module/components/icon/index.js.map +1 -0
- package/lib/module/components/icon/utils.js +188 -0
- package/lib/module/components/icon/utils.js.map +1 -0
- package/lib/module/components/index.js +16 -0
- package/lib/module/components/index.js.map +1 -0
- package/lib/module/components/page-indicator/PageIndicator.js +49 -0
- package/lib/module/components/page-indicator/PageIndicator.js.map +1 -0
- package/lib/module/components/page-indicator/PageIndicatorRoot.js +24 -0
- package/lib/module/components/page-indicator/PageIndicatorRoot.js.map +1 -0
- package/lib/module/components/page-indicator/hooks/use-page-indicator-colors.js +24 -0
- package/lib/module/components/page-indicator/hooks/use-page-indicator-colors.js.map +1 -0
- package/lib/module/components/page-indicator/hooks/use-page-indicator-core.js +20 -0
- package/lib/module/components/page-indicator/hooks/use-page-indicator-core.js.map +1 -0
- package/lib/module/components/page-indicator/hooks/use-page-indicator-progress.js +68 -0
- package/lib/module/components/page-indicator/hooks/use-page-indicator-progress.js.map +1 -0
- package/lib/module/components/page-indicator/index.js +5 -0
- package/lib/module/components/page-indicator/index.js.map +1 -0
- package/lib/module/components/page-indicator/utils.js +127 -0
- package/lib/module/components/page-indicator/utils.js.map +1 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/InactiveDot.js +50 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/InactiveDot.js.map +1 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/LoadingOrbit.js +165 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/LoadingOrbit.js.map +1 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/TravelingPill.js +60 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/TravelingPill.js.map +1 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/index.js +87 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/index.js.map +1 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/utils.js +28 -0
- package/lib/module/components/page-indicator/variants/DotIndicator/utils.js.map +1 -0
- package/lib/module/components/page-indicator/variants/PillIndicator/PillIndicatorDot.js +53 -0
- package/lib/module/components/page-indicator/variants/PillIndicator/PillIndicatorDot.js.map +1 -0
- package/lib/module/components/page-indicator/variants/PillIndicator/index.js +76 -0
- package/lib/module/components/page-indicator/variants/PillIndicator/index.js.map +1 -0
- package/lib/module/components/page-indicator/variants/PillIndicator/utils.js +47 -0
- package/lib/module/components/page-indicator/variants/PillIndicator/utils.js.map +1 -0
- package/lib/module/components/portal/PortalContext.js +20 -0
- package/lib/module/components/portal/PortalContext.js.map +1 -0
- package/lib/module/components/portal/PortalHost.js +23 -0
- package/lib/module/components/portal/PortalHost.js.map +1 -0
- package/lib/module/components/portal/PortalProvider.js +40 -0
- package/lib/module/components/portal/PortalProvider.js.map +1 -0
- package/lib/module/components/portal/index.js +6 -0
- package/lib/module/components/portal/index.js.map +1 -0
- package/lib/module/components/screen/Screen.js +100 -0
- package/lib/module/components/screen/Screen.js.map +1 -0
- package/lib/module/components/screen/ScreenContext.js +66 -0
- package/lib/module/components/screen/ScreenContext.js.map +1 -0
- package/lib/module/components/screen/ScreenFlatList.js +75 -0
- package/lib/module/components/screen/ScreenFlatList.js.map +1 -0
- package/lib/module/components/screen/ScreenScrollView.js +82 -0
- package/lib/module/components/screen/ScreenScrollView.js.map +1 -0
- package/lib/module/components/screen/index.js +7 -0
- package/lib/module/components/screen/index.js.map +1 -0
- package/lib/module/components/screen/utils.js +13 -0
- package/lib/module/components/screen/utils.js.map +1 -0
- package/lib/module/components/slot/Slot.js +38 -0
- package/lib/module/components/slot/Slot.js.map +1 -0
- package/lib/module/components/slot/index.js +10 -0
- package/lib/module/components/slot/index.js.map +1 -0
- package/lib/module/components/slot/utils.js +55 -0
- package/lib/module/components/slot/utils.js.map +1 -0
- package/lib/module/components/spinner/Spinner.js +132 -0
- package/lib/module/components/spinner/Spinner.js.map +1 -0
- package/lib/module/components/spinner/index.js +4 -0
- package/lib/module/components/spinner/index.js.map +1 -0
- package/lib/module/components/surface/Surface.js +74 -0
- package/lib/module/components/surface/Surface.js.map +1 -0
- package/lib/module/components/surface/index.js +4 -0
- package/lib/module/components/surface/index.js.map +1 -0
- package/lib/module/components/text/Text.js +67 -0
- package/lib/module/components/text/Text.js.map +1 -0
- package/lib/module/components/text/index.js +4 -0
- package/lib/module/components/text/index.js.map +1 -0
- package/lib/module/components/toast/Toast.js +350 -0
- package/lib/module/components/toast/Toast.js.map +1 -0
- package/lib/module/components/toast/ToastProvider.js +272 -0
- package/lib/module/components/toast/ToastProvider.js.map +1 -0
- package/lib/module/components/toast/index.js +5 -0
- package/lib/module/components/toast/index.js.map +1 -0
- package/lib/module/components/toast/parts/ToastAnimatedItem.js +168 -0
- package/lib/module/components/toast/parts/ToastAnimatedItem.js.map +1 -0
- package/lib/module/components/toast/types.js +4 -0
- package/lib/module/components/toast/types.js.map +1 -0
- package/lib/module/components/toast/utils/controller.js +19 -0
- package/lib/module/components/toast/utils/controller.js.map +1 -0
- package/lib/module/context/ThemeProvider.js +66 -0
- package/lib/module/context/ThemeProvider.js.map +1 -0
- package/lib/module/context/index.js +4 -0
- package/lib/module/context/index.js.map +1 -0
- package/lib/module/index.js +8 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/theme/configure.js +152 -0
- package/lib/module/theme/configure.js.map +1 -0
- package/lib/module/theme/index.js +22 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/runtime.js +25 -0
- package/lib/module/theme/runtime.js.map +1 -0
- package/lib/module/theme/theme.js +121 -0
- package/lib/module/theme/theme.js.map +1 -0
- package/lib/module/theme/tokens/dark.js +109 -0
- package/lib/module/theme/tokens/dark.js.map +1 -0
- package/lib/module/theme/tokens/light.js +115 -0
- package/lib/module/theme/tokens/light.js.map +1 -0
- package/lib/module/theme/tokens/primitives.js +228 -0
- package/lib/module/theme/tokens/primitives.js.map +1 -0
- package/lib/module/theme/types.js +4 -0
- package/lib/module/theme/types.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/accent-utils.js +52 -0
- package/lib/module/utils/accent-utils.js.map +1 -0
- package/lib/module/utils/color-utils.js +53 -0
- package/lib/module/utils/color-utils.js.map +1 -0
- package/lib/module/utils/deep-merge.js +28 -0
- package/lib/module/utils/deep-merge.js.map +1 -0
- package/lib/module/utils/resolve-theme-color.js +20 -0
- package/lib/module/utils/resolve-theme-color.js.map +1 -0
- package/lib/module/utils/typography.js +13 -0
- package/lib/module/utils/typography.js.map +1 -0
- package/lib/module/utils/unflatten.js +35 -0
- package/lib/module/utils/unflatten.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/components/avatar/Avatar.d.ts +3 -0
- package/lib/typescript/src/components/avatar/Avatar.d.ts.map +1 -0
- package/lib/typescript/src/components/avatar/index.d.ts +3 -0
- package/lib/typescript/src/components/avatar/index.d.ts.map +1 -0
- package/lib/typescript/src/components/avatar/types.d.ts +30 -0
- package/lib/typescript/src/components/avatar/types.d.ts.map +1 -0
- package/lib/typescript/src/components/box/Box.d.ts +12 -0
- package/lib/typescript/src/components/box/Box.d.ts.map +1 -0
- package/lib/typescript/src/components/box/index.d.ts +4 -0
- package/lib/typescript/src/components/box/index.d.ts.map +1 -0
- package/lib/typescript/src/components/box/utils.d.ts +39 -0
- package/lib/typescript/src/components/box/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/button/Button.d.ts +46 -0
- package/lib/typescript/src/components/button/Button.d.ts.map +1 -0
- package/lib/typescript/src/components/button/index.d.ts +3 -0
- package/lib/typescript/src/components/button/index.d.ts.map +1 -0
- package/lib/typescript/src/components/header/Header.d.ts +22 -0
- package/lib/typescript/src/components/header/Header.d.ts.map +1 -0
- package/lib/typescript/src/components/header/header-buttons.d.ts +16 -0
- package/lib/typescript/src/components/header/header-buttons.d.ts.map +1 -0
- package/lib/typescript/src/components/header/index.d.ts +7 -0
- package/lib/typescript/src/components/header/index.d.ts.map +1 -0
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts +25 -0
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts.map +1 -0
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts +28 -0
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts.map +1 -0
- package/lib/typescript/src/components/icon/Icon.d.ts +22 -0
- package/lib/typescript/src/components/icon/Icon.d.ts.map +1 -0
- package/lib/typescript/src/components/icon/index.d.ts +3 -0
- package/lib/typescript/src/components/icon/index.d.ts.map +1 -0
- package/lib/typescript/src/components/icon/utils.d.ts +4 -0
- package/lib/typescript/src/components/icon/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +14 -0
- package/lib/typescript/src/components/index.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/PageIndicator.d.ts +48 -0
- package/lib/typescript/src/components/page-indicator/PageIndicator.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/PageIndicatorRoot.d.ts +13 -0
- package/lib/typescript/src/components/page-indicator/PageIndicatorRoot.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/hooks/use-page-indicator-colors.d.ts +14 -0
- package/lib/typescript/src/components/page-indicator/hooks/use-page-indicator-colors.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/hooks/use-page-indicator-core.d.ts +11 -0
- package/lib/typescript/src/components/page-indicator/hooks/use-page-indicator-core.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/hooks/use-page-indicator-progress.d.ts +19 -0
- package/lib/typescript/src/components/page-indicator/hooks/use-page-indicator-progress.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/index.d.ts +4 -0
- package/lib/typescript/src/components/page-indicator/index.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/utils.d.ts +36 -0
- package/lib/typescript/src/components/page-indicator/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/InactiveDot.d.ts +14 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/InactiveDot.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/LoadingOrbit.d.ts +11 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/LoadingOrbit.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/TravelingPill.d.ts +15 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/TravelingPill.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/index.d.ts +32 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/index.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/utils.d.ts +14 -0
- package/lib/typescript/src/components/page-indicator/variants/DotIndicator/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/PillIndicator/PillIndicatorDot.d.ts +16 -0
- package/lib/typescript/src/components/page-indicator/variants/PillIndicator/PillIndicatorDot.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/PillIndicator/index.d.ts +28 -0
- package/lib/typescript/src/components/page-indicator/variants/PillIndicator/index.d.ts.map +1 -0
- package/lib/typescript/src/components/page-indicator/variants/PillIndicator/utils.d.ts +21 -0
- package/lib/typescript/src/components/page-indicator/variants/PillIndicator/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/portal/PortalContext.d.ts +19 -0
- package/lib/typescript/src/components/portal/PortalContext.d.ts.map +1 -0
- package/lib/typescript/src/components/portal/PortalHost.d.ts +7 -0
- package/lib/typescript/src/components/portal/PortalHost.d.ts.map +1 -0
- package/lib/typescript/src/components/portal/PortalProvider.d.ts +11 -0
- package/lib/typescript/src/components/portal/PortalProvider.d.ts.map +1 -0
- package/lib/typescript/src/components/portal/index.d.ts +6 -0
- package/lib/typescript/src/components/portal/index.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/Screen.d.ts +53 -0
- package/lib/typescript/src/components/screen/Screen.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/ScreenContext.d.ts +64 -0
- package/lib/typescript/src/components/screen/ScreenContext.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/ScreenFlatList.d.ts +26 -0
- package/lib/typescript/src/components/screen/ScreenFlatList.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/ScreenScrollView.d.ts +36 -0
- package/lib/typescript/src/components/screen/ScreenScrollView.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/index.d.ts +9 -0
- package/lib/typescript/src/components/screen/index.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/utils.d.ts +10 -0
- package/lib/typescript/src/components/screen/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/slot/Slot.d.ts +17 -0
- package/lib/typescript/src/components/slot/Slot.d.ts.map +1 -0
- package/lib/typescript/src/components/slot/index.d.ts +8 -0
- package/lib/typescript/src/components/slot/index.d.ts.map +1 -0
- package/lib/typescript/src/components/slot/utils.d.ts +17 -0
- package/lib/typescript/src/components/slot/utils.d.ts.map +1 -0
- package/lib/typescript/src/components/spinner/Spinner.d.ts +18 -0
- package/lib/typescript/src/components/spinner/Spinner.d.ts.map +1 -0
- package/lib/typescript/src/components/spinner/index.d.ts +3 -0
- package/lib/typescript/src/components/spinner/index.d.ts.map +1 -0
- package/lib/typescript/src/components/surface/Surface.d.ts +31 -0
- package/lib/typescript/src/components/surface/Surface.d.ts.map +1 -0
- package/lib/typescript/src/components/surface/index.d.ts +3 -0
- package/lib/typescript/src/components/surface/index.d.ts.map +1 -0
- package/lib/typescript/src/components/text/Text.d.ts +23 -0
- package/lib/typescript/src/components/text/Text.d.ts.map +1 -0
- package/lib/typescript/src/components/text/index.d.ts +3 -0
- package/lib/typescript/src/components/text/index.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/Toast.d.ts +71 -0
- package/lib/typescript/src/components/toast/Toast.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/ToastProvider.d.ts +4 -0
- package/lib/typescript/src/components/toast/ToastProvider.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/index.d.ts +5 -0
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/parts/ToastAnimatedItem.d.ts +18 -0
- package/lib/typescript/src/components/toast/parts/ToastAnimatedItem.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/types.d.ts +62 -0
- package/lib/typescript/src/components/toast/types.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/utils/controller.d.ts +5 -0
- package/lib/typescript/src/components/toast/utils/controller.d.ts.map +1 -0
- package/lib/typescript/src/context/ThemeProvider.d.ts +29 -0
- package/lib/typescript/src/context/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/src/context/index.d.ts +3 -0
- package/lib/typescript/src/context/index.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/theme/configure.d.ts +47 -0
- package/lib/typescript/src/theme/configure.d.ts.map +1 -0
- package/lib/typescript/src/theme/index.d.ts +11 -0
- package/lib/typescript/src/theme/index.d.ts.map +1 -0
- package/lib/typescript/src/theme/runtime.d.ts +7 -0
- package/lib/typescript/src/theme/runtime.d.ts.map +1 -0
- package/lib/typescript/src/theme/theme.d.ts +22 -0
- package/lib/typescript/src/theme/theme.d.ts.map +1 -0
- package/lib/typescript/src/theme/tokens/dark.d.ts +100 -0
- package/lib/typescript/src/theme/tokens/dark.d.ts.map +1 -0
- package/lib/typescript/src/theme/tokens/light.d.ts +106 -0
- package/lib/typescript/src/theme/tokens/light.d.ts.map +1 -0
- package/lib/typescript/src/theme/tokens/primitives.d.ts +212 -0
- package/lib/typescript/src/theme/tokens/primitives.d.ts.map +1 -0
- package/lib/typescript/src/theme/types.d.ts +273 -0
- package/lib/typescript/src/theme/types.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +4 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/accent-utils.d.ts +4 -0
- package/lib/typescript/src/utils/accent-utils.d.ts.map +1 -0
- package/lib/typescript/src/utils/color-utils.d.ts +11 -0
- package/lib/typescript/src/utils/color-utils.d.ts.map +1 -0
- package/lib/typescript/src/utils/deep-merge.d.ts +11 -0
- package/lib/typescript/src/utils/deep-merge.d.ts.map +1 -0
- package/lib/typescript/src/utils/resolve-theme-color.d.ts +12 -0
- package/lib/typescript/src/utils/resolve-theme-color.d.ts.map +1 -0
- package/lib/typescript/src/utils/typography.d.ts +6 -0
- package/lib/typescript/src/utils/typography.d.ts.map +1 -0
- package/lib/typescript/src/utils/unflatten.d.ts +12 -0
- package/lib/typescript/src/utils/unflatten.d.ts.map +1 -0
- package/package.json +137 -0
- package/src/components/avatar/Avatar.tsx +146 -0
- package/src/components/avatar/index.ts +8 -0
- package/src/components/avatar/types.ts +35 -0
- package/src/components/box/Box.tsx +59 -0
- package/src/components/box/index.ts +8 -0
- package/src/components/box/utils.ts +181 -0
- package/src/components/button/Button.tsx +313 -0
- package/src/components/button/index.ts +8 -0
- package/src/components/header/Header.ts +22 -0
- package/src/components/header/header-buttons.tsx +103 -0
- package/src/components/header/index.ts +11 -0
- package/src/components/header/variants/LargeTitleHeader/index.tsx +390 -0
- package/src/components/header/variants/TitleHeader/index.tsx +194 -0
- package/src/components/icon/Icon.tsx +74 -0
- package/src/components/icon/index.ts +2 -0
- package/src/components/icon/utils.tsx +147 -0
- package/src/components/index.ts +13 -0
- package/src/components/page-indicator/PageIndicator.tsx +100 -0
- package/src/components/page-indicator/PageIndicatorRoot.tsx +41 -0
- package/src/components/page-indicator/hooks/use-page-indicator-colors.ts +65 -0
- package/src/components/page-indicator/hooks/use-page-indicator-core.ts +34 -0
- package/src/components/page-indicator/hooks/use-page-indicator-progress.ts +122 -0
- package/src/components/page-indicator/index.ts +13 -0
- package/src/components/page-indicator/utils.ts +208 -0
- package/src/components/page-indicator/variants/DotIndicator/InactiveDot.tsx +70 -0
- package/src/components/page-indicator/variants/DotIndicator/LoadingOrbit.tsx +201 -0
- package/src/components/page-indicator/variants/DotIndicator/TravelingPill.tsx +80 -0
- package/src/components/page-indicator/variants/DotIndicator/index.tsx +145 -0
- package/src/components/page-indicator/variants/DotIndicator/utils.ts +28 -0
- package/src/components/page-indicator/variants/PillIndicator/PillIndicatorDot.tsx +107 -0
- package/src/components/page-indicator/variants/PillIndicator/index.tsx +149 -0
- package/src/components/page-indicator/variants/PillIndicator/utils.ts +63 -0
- package/src/components/portal/PortalContext.tsx +27 -0
- package/src/components/portal/PortalHost.tsx +20 -0
- package/src/components/portal/PortalProvider.tsx +44 -0
- package/src/components/portal/index.ts +5 -0
- package/src/components/screen/Screen.tsx +163 -0
- package/src/components/screen/ScreenContext.tsx +144 -0
- package/src/components/screen/ScreenFlatList.tsx +121 -0
- package/src/components/screen/ScreenScrollView.tsx +130 -0
- package/src/components/screen/index.ts +8 -0
- package/src/components/screen/utils.ts +17 -0
- package/src/components/slot/Slot.tsx +56 -0
- package/src/components/slot/index.ts +8 -0
- package/src/components/slot/utils.ts +61 -0
- package/src/components/spinner/Spinner.tsx +153 -0
- package/src/components/spinner/index.ts +2 -0
- package/src/components/surface/Surface.tsx +100 -0
- package/src/components/surface/index.ts +2 -0
- package/src/components/text/Text.tsx +115 -0
- package/src/components/text/index.ts +2 -0
- package/src/components/toast/Toast.tsx +477 -0
- package/src/components/toast/ToastProvider.tsx +403 -0
- package/src/components/toast/index.ts +26 -0
- package/src/components/toast/parts/ToastAnimatedItem.tsx +184 -0
- package/src/components/toast/types.ts +75 -0
- package/src/components/toast/utils/controller.ts +23 -0
- package/src/context/ThemeProvider.tsx +97 -0
- package/src/context/index.ts +2 -0
- package/src/index.tsx +6 -0
- package/src/theme/configure.ts +215 -0
- package/src/theme/index.ts +72 -0
- package/src/theme/runtime.ts +27 -0
- package/src/theme/theme.ts +152 -0
- package/src/theme/tokens/dark.ts +117 -0
- package/src/theme/tokens/light.ts +123 -0
- package/src/theme/tokens/primitives.ts +232 -0
- package/src/theme/types.ts +384 -0
- package/src/types.ts +1 -0
- package/src/utils/accent-utils.ts +58 -0
- package/src/utils/color-utils.ts +51 -0
- package/src/utils/deep-merge.ts +36 -0
- package/src/utils/resolve-theme-color.ts +27 -0
- package/src/utils/typography.ts +15 -0
- package/src/utils/unflatten.ts +36 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
type PropsWithChildren,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
9
|
+
|
|
10
|
+
import { useUnistyles } from 'react-native-unistyles';
|
|
11
|
+
|
|
12
|
+
import { configureTerraUI, getIsConfigured } from '../theme/configure';
|
|
13
|
+
import { applyAccent, applyScheme, getCurrentAccent } from '../theme/runtime';
|
|
14
|
+
import type { Scheme, TerraTheme } from '../theme/types';
|
|
15
|
+
|
|
16
|
+
// Ensure the default theme is registered on first import, unless the app already
|
|
17
|
+
// configured a custom one (e.g. via `react-native-terra-ui/theme` at entry).
|
|
18
|
+
if (!getIsConfigured()) {
|
|
19
|
+
configureTerraUI();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ThemeContextValue {
|
|
23
|
+
accent: string | undefined;
|
|
24
|
+
setAccent: (name: string) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Root provider for Terra UI. Wrap your app once near the root.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <TerraUIProvider>
|
|
34
|
+
* <RootNavigator />
|
|
35
|
+
* </TerraUIProvider>
|
|
36
|
+
*/
|
|
37
|
+
export const TerraUIProvider = ({ children }: PropsWithChildren) => {
|
|
38
|
+
const [accent, setAccentState] = useState<string | undefined>(() =>
|
|
39
|
+
getCurrentAccent()
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const setAccent = useCallback((name: string) => {
|
|
43
|
+
applyAccent(name);
|
|
44
|
+
setAccentState(name);
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
const value = useMemo<ThemeContextValue>(
|
|
48
|
+
() => ({ accent, setAccent }),
|
|
49
|
+
[accent, setAccent]
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export interface UseThemeResult {
|
|
58
|
+
/** The active resolved theme. */
|
|
59
|
+
theme: TerraTheme;
|
|
60
|
+
/** Active color scheme. */
|
|
61
|
+
scheme: Scheme;
|
|
62
|
+
/** Switch scheme (disables system-adaptive theming). */
|
|
63
|
+
setScheme: (scheme: Scheme) => void;
|
|
64
|
+
/** Active accent name, if any. */
|
|
65
|
+
accent: string | undefined;
|
|
66
|
+
/** Switch to a registered accent. */
|
|
67
|
+
setAccent: (name: string) => void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Access the active theme and switch scheme / accent / radius.
|
|
72
|
+
* Must be used under {@link TerraUIProvider}.
|
|
73
|
+
*/
|
|
74
|
+
export function useTheme(): UseThemeResult {
|
|
75
|
+
const { theme, rt } = useUnistyles();
|
|
76
|
+
const ctx = useContext(ThemeContext);
|
|
77
|
+
|
|
78
|
+
const setScheme = useCallback((scheme: Scheme) => {
|
|
79
|
+
applyScheme(scheme);
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
theme,
|
|
84
|
+
scheme: (rt.themeName ?? 'light') as Scheme,
|
|
85
|
+
setScheme,
|
|
86
|
+
accent: ctx?.accent,
|
|
87
|
+
setAccent: ctx?.setAccent ?? noopSetAccent,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const noopSetAccent = (_name: string): void => {
|
|
92
|
+
if (__DEV__) {
|
|
93
|
+
console.warn(
|
|
94
|
+
'[react-native-terra-ui] setAccent called outside <TerraUIProvider>.'
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
};
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { Image } from 'react-native';
|
|
3
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
4
|
+
|
|
5
|
+
import { defaultIcons } from '#components/icon/utils';
|
|
6
|
+
import { normalizeAccent } from '#utils/accent-utils';
|
|
7
|
+
import { deepMerge } from '#utils/deep-merge';
|
|
8
|
+
|
|
9
|
+
import { buildRadiusScale, defaultDarkTheme, defaultLightTheme } from './theme';
|
|
10
|
+
import type {
|
|
11
|
+
ComponentDefaults,
|
|
12
|
+
DefaultRadiusToken,
|
|
13
|
+
ElevationKey,
|
|
14
|
+
NormalizedAccent,
|
|
15
|
+
RadiusComponent,
|
|
16
|
+
Scheme,
|
|
17
|
+
TerraConfig,
|
|
18
|
+
TerraIconComponent,
|
|
19
|
+
TerraImageComponent,
|
|
20
|
+
TerraImageContentFit,
|
|
21
|
+
TerraSemanticIconName,
|
|
22
|
+
TerraTheme,
|
|
23
|
+
TerraThemeOverride,
|
|
24
|
+
} from './types';
|
|
25
|
+
|
|
26
|
+
// ─── Default image component ──────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
const CONTENT_FIT_MAP = {
|
|
29
|
+
cover: 'cover',
|
|
30
|
+
contain: 'contain',
|
|
31
|
+
fill: 'stretch',
|
|
32
|
+
} as const satisfies Record<
|
|
33
|
+
TerraImageContentFit,
|
|
34
|
+
'cover' | 'contain' | 'stretch'
|
|
35
|
+
>;
|
|
36
|
+
|
|
37
|
+
const DefaultImage: TerraImageComponent = ({
|
|
38
|
+
contentFit = 'cover',
|
|
39
|
+
source,
|
|
40
|
+
style,
|
|
41
|
+
accessibilityLabel,
|
|
42
|
+
onError,
|
|
43
|
+
}) =>
|
|
44
|
+
createElement(Image, {
|
|
45
|
+
source,
|
|
46
|
+
style,
|
|
47
|
+
accessibilityLabel,
|
|
48
|
+
resizeMode: CONTENT_FIT_MAP[contentFit],
|
|
49
|
+
onError: onError ? () => onError() : undefined,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// ─── Radius / elevation defaults ─────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
/** Fallback when a component's radius is not configured. */
|
|
55
|
+
const DEFAULT_RADIUS: DefaultRadiusToken = 'md';
|
|
56
|
+
/** Fallback when the surface elevation is not configured. */
|
|
57
|
+
const DEFAULT_ELEVATION: ElevationKey = 'none';
|
|
58
|
+
|
|
59
|
+
type ResolvedRadius = Record<RadiusComponent, DefaultRadiusToken>;
|
|
60
|
+
|
|
61
|
+
/** Resolves each component's default radius from the `components` config. */
|
|
62
|
+
const resolveDefaultRadius = (
|
|
63
|
+
components?: ComponentDefaults
|
|
64
|
+
): ResolvedRadius => ({
|
|
65
|
+
button: components?.button?.radius ?? DEFAULT_RADIUS,
|
|
66
|
+
surface: components?.surface?.radius ?? DEFAULT_RADIUS,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// ─── Unistyles module augmentation ────────────────────────────────────────────
|
|
70
|
+
declare module 'react-native-unistyles' {
|
|
71
|
+
export interface UnistylesThemes {
|
|
72
|
+
light: TerraTheme;
|
|
73
|
+
dark: TerraTheme;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface Registry {
|
|
78
|
+
baseLight: TerraTheme;
|
|
79
|
+
baseDark: TerraTheme;
|
|
80
|
+
accents: Record<string, NormalizedAccent>;
|
|
81
|
+
currentAccent?: string;
|
|
82
|
+
defaultRadius: ResolvedRadius;
|
|
83
|
+
surfaceElevation: ElevationKey;
|
|
84
|
+
icons: Record<string, TerraIconComponent>;
|
|
85
|
+
imageComponent: TerraImageComponent;
|
|
86
|
+
configured: boolean;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const registry: Registry = {
|
|
90
|
+
baseLight: defaultLightTheme,
|
|
91
|
+
baseDark: defaultDarkTheme,
|
|
92
|
+
accents: {},
|
|
93
|
+
currentAccent: undefined,
|
|
94
|
+
defaultRadius: resolveDefaultRadius(),
|
|
95
|
+
surfaceElevation: DEFAULT_ELEVATION,
|
|
96
|
+
icons: {},
|
|
97
|
+
imageComponent: DefaultImage,
|
|
98
|
+
configured: false,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/** @internal */
|
|
102
|
+
export const getRegistry = (): Registry => registry;
|
|
103
|
+
|
|
104
|
+
export const getIsConfigured = (): boolean => registry.configured;
|
|
105
|
+
|
|
106
|
+
export const getAccentNames = (): string[] => Object.keys(registry.accents);
|
|
107
|
+
|
|
108
|
+
export const getImageComponent = (): TerraImageComponent =>
|
|
109
|
+
registry.imageComponent;
|
|
110
|
+
|
|
111
|
+
export const getIcon = (name: string): TerraIconComponent | undefined =>
|
|
112
|
+
registry.icons[name] ?? defaultIcons[name as TerraSemanticIconName];
|
|
113
|
+
|
|
114
|
+
export const getRequiredIcon = (
|
|
115
|
+
name: TerraSemanticIconName
|
|
116
|
+
): TerraIconComponent => registry.icons[name] ?? defaultIcons[name];
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The configured default corner radius for a component (Button, Surface).
|
|
120
|
+
* Set via {@link configureTerraUI}; defaults to `'md'`.
|
|
121
|
+
*/
|
|
122
|
+
export const getDefaultRadius = (
|
|
123
|
+
component: RadiusComponent
|
|
124
|
+
): DefaultRadiusToken => registry.defaultRadius[component];
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The configured default drop-shadow depth for Surface (`'none'` = no shadow).
|
|
128
|
+
* Set via {@link configureTerraUI}; defaults to `'none'`.
|
|
129
|
+
*/
|
|
130
|
+
export const getSurfaceElevation = (): ElevationKey =>
|
|
131
|
+
registry.surfaceElevation;
|
|
132
|
+
|
|
133
|
+
/** Resolves a scheme's theme = base ⊕ the named accent's partial override. */
|
|
134
|
+
export function resolveTheme(scheme: Scheme, accentName?: string): TerraTheme {
|
|
135
|
+
const base = scheme === 'light' ? registry.baseLight : registry.baseDark;
|
|
136
|
+
const accent = accentName ? registry.accents[accentName] : undefined;
|
|
137
|
+
return deepMerge(base, accent ? accent[scheme] : undefined);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const mergeThemeOverride = (
|
|
141
|
+
theme: TerraTheme,
|
|
142
|
+
override?: TerraThemeOverride
|
|
143
|
+
): TerraTheme => {
|
|
144
|
+
if (!override) return theme;
|
|
145
|
+
|
|
146
|
+
const { radius, ...rest } = override;
|
|
147
|
+
let next = deepMerge(theme, rest);
|
|
148
|
+
|
|
149
|
+
if (radius) {
|
|
150
|
+
const { base, ...radiusTokens } = radius;
|
|
151
|
+
if (base != null) {
|
|
152
|
+
next = deepMerge(next, { radius: buildRadiusScale(base) });
|
|
153
|
+
}
|
|
154
|
+
next = deepMerge(next, { radius: radiusTokens });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return next;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Configure Terra UI's themes. Call ONCE, as early as possible — before any
|
|
162
|
+
* component renders (e.g. top of the app entry, imported from
|
|
163
|
+
* `react-native-terra-ui/theme`). With no arguments it registers the default
|
|
164
|
+
* theme; `<TerraUIProvider>` calls it for you if you haven't.
|
|
165
|
+
*/
|
|
166
|
+
export function configureTerraUI(config: TerraConfig = {}): void {
|
|
167
|
+
if (registry.configured) {
|
|
168
|
+
if (__DEV__ && Object.keys(config).length > 0) {
|
|
169
|
+
console.warn(
|
|
170
|
+
'[react-native-terra-ui] configureTerraUI() was called more than once; the later call was ignored.'
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
registry.configured = true;
|
|
176
|
+
|
|
177
|
+
registry.baseLight = mergeThemeOverride(
|
|
178
|
+
mergeThemeOverride(defaultLightTheme, config.shared),
|
|
179
|
+
config.schemes?.light
|
|
180
|
+
);
|
|
181
|
+
registry.baseDark = mergeThemeOverride(
|
|
182
|
+
mergeThemeOverride(defaultDarkTheme, config.shared),
|
|
183
|
+
config.schemes?.dark
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
registry.defaultRadius = resolveDefaultRadius(config.components);
|
|
187
|
+
registry.surfaceElevation =
|
|
188
|
+
config.components?.surface?.elevation ?? DEFAULT_ELEVATION;
|
|
189
|
+
registry.icons = config.icons ?? {};
|
|
190
|
+
registry.imageComponent = config.image ?? DefaultImage;
|
|
191
|
+
|
|
192
|
+
registry.accents = {};
|
|
193
|
+
for (const [name, accent] of Object.entries(config.accents ?? {})) {
|
|
194
|
+
registry.accents[name] = normalizeAccent(accent);
|
|
195
|
+
}
|
|
196
|
+
const { defaultAccent } = config;
|
|
197
|
+
registry.currentAccent =
|
|
198
|
+
defaultAccent && registry.accents[defaultAccent]
|
|
199
|
+
? defaultAccent
|
|
200
|
+
: undefined;
|
|
201
|
+
|
|
202
|
+
const themes = {
|
|
203
|
+
light: resolveTheme('light', registry.currentAccent),
|
|
204
|
+
dark: resolveTheme('dark', registry.currentAccent),
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const adaptive = config.adaptiveThemes ?? true;
|
|
208
|
+
const settings = config.initialScheme
|
|
209
|
+
? { initialTheme: config.initialScheme }
|
|
210
|
+
: adaptive
|
|
211
|
+
? { adaptiveThemes: true as const }
|
|
212
|
+
: { initialTheme: 'light' as const };
|
|
213
|
+
|
|
214
|
+
StyleSheet.configure({ themes, settings });
|
|
215
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Public theme API for `react-native-terra-ui` / `react-native-terra-ui/theme`.
|
|
2
|
+
//
|
|
3
|
+
// Token DATA lives in ./tokens/*.ts (flat, Figma-style, untyped); TYPES live in
|
|
4
|
+
// ./types; pure helpers live in #/utils. Raw primitive data (palette, spacing,
|
|
5
|
+
// radius, elevation scales, typography) is intentionally NOT re-exported — the
|
|
6
|
+
// resolved `defaultLightTheme` / `defaultDarkTheme` are the public surface.
|
|
7
|
+
|
|
8
|
+
// ─── Utilities (color resolution + accent/merge/typography helpers) ──────────
|
|
9
|
+
export { normalizeAccent } from '#utils/accent-utils';
|
|
10
|
+
export { readableOn, shade, withAlpha } from '#utils/color-utils';
|
|
11
|
+
export type { DeepPartial } from '#utils/deep-merge';
|
|
12
|
+
export { deepMerge } from '#utils/deep-merge';
|
|
13
|
+
export { resolveThemeColor } from '#utils/resolve-theme-color';
|
|
14
|
+
export { FONT_WEIGHT_VALUE, SYSTEM_FONT } from '#utils/typography';
|
|
15
|
+
// ─── Config + runtime ───────────────────────────────────────────────────────
|
|
16
|
+
export {
|
|
17
|
+
configureTerraUI,
|
|
18
|
+
getAccentNames,
|
|
19
|
+
getDefaultRadius,
|
|
20
|
+
getIcon,
|
|
21
|
+
getImageComponent,
|
|
22
|
+
getIsConfigured,
|
|
23
|
+
getRequiredIcon,
|
|
24
|
+
getSurfaceElevation,
|
|
25
|
+
resolveTheme,
|
|
26
|
+
} from './configure';
|
|
27
|
+
export { applyAccent, applyScheme, getCurrentAccent } from './runtime';
|
|
28
|
+
// ─── Default themes ───────────────────────────────────────────────────────────
|
|
29
|
+
export { defaultDarkTheme, defaultLightTheme } from './theme';
|
|
30
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
31
|
+
export type {
|
|
32
|
+
Accent,
|
|
33
|
+
AccentOverride,
|
|
34
|
+
AccentShorthand,
|
|
35
|
+
ActionColorToken,
|
|
36
|
+
BackgroundColorToken,
|
|
37
|
+
BorderColorToken,
|
|
38
|
+
ButtonDefaults,
|
|
39
|
+
ColorToken,
|
|
40
|
+
ComponentDefaults,
|
|
41
|
+
ContentColorToken,
|
|
42
|
+
DefaultRadiusToken,
|
|
43
|
+
ElevationKey,
|
|
44
|
+
ElevationScale,
|
|
45
|
+
ElevationStyle,
|
|
46
|
+
FontWeightToken,
|
|
47
|
+
LayoutTokens,
|
|
48
|
+
OpacityTokens,
|
|
49
|
+
RadiusComponent,
|
|
50
|
+
RadiusKey,
|
|
51
|
+
Scheme,
|
|
52
|
+
SpacingKey,
|
|
53
|
+
StatusColorToken,
|
|
54
|
+
SurfaceColorToken,
|
|
55
|
+
SurfaceDefaults,
|
|
56
|
+
TerraConfig,
|
|
57
|
+
TerraIconComponent,
|
|
58
|
+
TerraIconName,
|
|
59
|
+
TerraIconProps,
|
|
60
|
+
TerraImageComponent,
|
|
61
|
+
TerraImageContentFit,
|
|
62
|
+
TerraImageProps,
|
|
63
|
+
TerraSemanticIconName,
|
|
64
|
+
TerraTheme,
|
|
65
|
+
TerraThemeOverride,
|
|
66
|
+
TextColorToken,
|
|
67
|
+
TextVariant,
|
|
68
|
+
ThemeColor,
|
|
69
|
+
ThemeRadiusOverride,
|
|
70
|
+
TypeStyle,
|
|
71
|
+
Typography,
|
|
72
|
+
} from './types';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { UnistylesRuntime } from 'react-native-unistyles';
|
|
2
|
+
|
|
3
|
+
import { getRegistry, resolveTheme } from './configure';
|
|
4
|
+
import type { Scheme } from './types';
|
|
5
|
+
|
|
6
|
+
/** Apply a named accent at runtime by updating both registered themes. */
|
|
7
|
+
export function applyAccent(name: string): void {
|
|
8
|
+
const registry = getRegistry();
|
|
9
|
+
if (!registry.accents[name]) {
|
|
10
|
+
if (__DEV__) {
|
|
11
|
+
console.warn(`[react-native-terra-ui] Unknown accent "${name}".`);
|
|
12
|
+
}
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
registry.currentAccent = name;
|
|
16
|
+
UnistylesRuntime.updateTheme('light', () => resolveTheme('light', name));
|
|
17
|
+
UnistylesRuntime.updateTheme('dark', () => resolveTheme('dark', name));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const getCurrentAccent = (): string | undefined =>
|
|
21
|
+
getRegistry().currentAccent;
|
|
22
|
+
|
|
23
|
+
/** Switch the active color scheme, disabling adaptive (system) theming. */
|
|
24
|
+
export function applyScheme(scheme: Scheme): void {
|
|
25
|
+
UnistylesRuntime.setAdaptiveThemes(false);
|
|
26
|
+
UnistylesRuntime.setTheme(scheme);
|
|
27
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { unflatten } from '#utils/unflatten';
|
|
2
|
+
|
|
3
|
+
import { dark } from './tokens/dark';
|
|
4
|
+
import { light } from './tokens/light';
|
|
5
|
+
import { primitives } from './tokens/primitives';
|
|
6
|
+
import type {
|
|
7
|
+
ElevationScale,
|
|
8
|
+
LayoutTokens,
|
|
9
|
+
OpacityTokens,
|
|
10
|
+
RadiusKey,
|
|
11
|
+
SpacingKey,
|
|
12
|
+
TerraTheme,
|
|
13
|
+
ThemeColor,
|
|
14
|
+
Typography,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Resolves {palette.key} reference notation against a source flat-token map.
|
|
19
|
+
* Non-reference values pass through unchanged.
|
|
20
|
+
*/
|
|
21
|
+
function resolveRefs(
|
|
22
|
+
flat: Record<string, unknown>,
|
|
23
|
+
source: Record<string, unknown>
|
|
24
|
+
): Record<string, unknown> {
|
|
25
|
+
const out: Record<string, unknown> = {};
|
|
26
|
+
for (const [k, v] of Object.entries(flat)) {
|
|
27
|
+
out[k] =
|
|
28
|
+
typeof v === 'string' && v.startsWith('{') && v.endsWith('}')
|
|
29
|
+
? (source[v.slice(1, -1)] ?? v)
|
|
30
|
+
: v;
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Splits a flat dotted-key token map into a one-level-deep object keyed by
|
|
37
|
+
* the first path segment (the category). The category prefix is stripped from
|
|
38
|
+
* each key, leaving a flat map per category.
|
|
39
|
+
*
|
|
40
|
+
* Example:
|
|
41
|
+
* { 'color.surface.default': '#fff', 'color.action.bg.primary': '#009966' }
|
|
42
|
+
* → { color: { 'surface.default': '#fff', 'action.bg.primary': '#009966' } }
|
|
43
|
+
*/
|
|
44
|
+
function flattenByCategory(
|
|
45
|
+
tokens: Record<string, unknown>
|
|
46
|
+
): Record<string, Record<string, unknown>> {
|
|
47
|
+
const out: Record<string, Record<string, unknown>> = {};
|
|
48
|
+
for (const [key, value] of Object.entries(tokens)) {
|
|
49
|
+
const sep = key.indexOf('.');
|
|
50
|
+
const cat = sep === -1 ? key : key.slice(0, sep);
|
|
51
|
+
const rest = sep === -1 ? '' : key.slice(sep + 1);
|
|
52
|
+
if (out[cat] === undefined) {
|
|
53
|
+
out[cat] = {};
|
|
54
|
+
}
|
|
55
|
+
out[cat][rest] = value;
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Scheme-agnostic primitives, rebuilt once from the flat token data. Shared by
|
|
62
|
+
* both default themes (matching the previous behavior where spacing / radius /
|
|
63
|
+
* typography were singleton constants). `palette` is present at runtime for
|
|
64
|
+
* Figma parity but is not part of {@link TerraTheme}. Only the radius BASE is
|
|
65
|
+
* authored here (`radius.base`); the full scale is derived via
|
|
66
|
+
* {@link buildRadiusScale}.
|
|
67
|
+
*/
|
|
68
|
+
const prim = unflatten<{
|
|
69
|
+
spacing: Record<SpacingKey, number>;
|
|
70
|
+
radius: { base: number };
|
|
71
|
+
typography: Typography;
|
|
72
|
+
opacity: OpacityTokens;
|
|
73
|
+
layout: LayoutTokens;
|
|
74
|
+
}>(primitives);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Default base corner radius (dp) — the `lg` (×1) step — taken from the
|
|
78
|
+
* `radius.base` primitive. The rest of the scale is derived from it via
|
|
79
|
+
* {@link RADIUS_MULTIPLIERS}; override at runtime with
|
|
80
|
+
* `configureTerraUI({ shared: { radius: { base } } })`, or change the
|
|
81
|
+
* `radius.base` token.
|
|
82
|
+
*/
|
|
83
|
+
export const DEFAULT_RADIUS_BASE = prim.radius.base;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Per-token multipliers applied to the base radius (DaisyUI-style). `none` (0)
|
|
87
|
+
* and `full` (9999) are fixed and not scaled.
|
|
88
|
+
*/
|
|
89
|
+
export const RADIUS_MULTIPLIERS: Record<
|
|
90
|
+
Exclude<RadiusKey, 'none' | 'full'>,
|
|
91
|
+
number
|
|
92
|
+
> = {
|
|
93
|
+
xs: 0.25,
|
|
94
|
+
sm: 0.5,
|
|
95
|
+
md: 0.75,
|
|
96
|
+
lg: 1,
|
|
97
|
+
xl: 1.5,
|
|
98
|
+
'2xl': 2,
|
|
99
|
+
'3xl': 3,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Builds the full radius scale from a single base value. Derived steps keep
|
|
104
|
+
* their exact (possibly fractional) dp; `none`/`full` are constant.
|
|
105
|
+
*/
|
|
106
|
+
export function buildRadiusScale(
|
|
107
|
+
base: number = DEFAULT_RADIUS_BASE
|
|
108
|
+
): Record<RadiusKey, number> {
|
|
109
|
+
const scale = { none: 0, full: 9999 } as Record<RadiusKey, number>;
|
|
110
|
+
for (const key of Object.keys(
|
|
111
|
+
RADIUS_MULTIPLIERS
|
|
112
|
+
) as (keyof typeof RADIUS_MULTIPLIERS)[]) {
|
|
113
|
+
scale[key] = base * RADIUS_MULTIPLIERS[key];
|
|
114
|
+
}
|
|
115
|
+
return scale;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const defaultRadius = buildRadiusScale();
|
|
119
|
+
|
|
120
|
+
const lightByCategory = flattenByCategory(resolveRefs(light, primitives));
|
|
121
|
+
const darkByCategory = flattenByCategory(resolveRefs(dark, primitives));
|
|
122
|
+
|
|
123
|
+
// color: flat map — accessed as theme.color['action.bg.primary.hover']
|
|
124
|
+
// elevation: re-unflattened for structured access — theme.elevation.sm.shadowRadius
|
|
125
|
+
const lightTokens = {
|
|
126
|
+
color: lightByCategory.color as unknown as ThemeColor,
|
|
127
|
+
elevation: unflatten<ElevationScale>(lightByCategory.elevation ?? {}),
|
|
128
|
+
};
|
|
129
|
+
const darkTokens = {
|
|
130
|
+
color: darkByCategory.color as unknown as ThemeColor,
|
|
131
|
+
elevation: unflatten<ElevationScale>(darkByCategory.elevation ?? {}),
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const defaultLightTheme: TerraTheme = {
|
|
135
|
+
color: lightTokens.color,
|
|
136
|
+
elevation: lightTokens.elevation,
|
|
137
|
+
spacing: prim.spacing,
|
|
138
|
+
radius: defaultRadius,
|
|
139
|
+
typography: prim.typography,
|
|
140
|
+
opacity: prim.opacity,
|
|
141
|
+
layout: prim.layout,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const defaultDarkTheme: TerraTheme = {
|
|
145
|
+
color: darkTokens.color,
|
|
146
|
+
elevation: darkTokens.elevation,
|
|
147
|
+
spacing: prim.spacing,
|
|
148
|
+
radius: defaultRadius,
|
|
149
|
+
typography: prim.typography,
|
|
150
|
+
opacity: prim.opacity,
|
|
151
|
+
layout: prim.layout,
|
|
152
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dark-scheme color tokens — flat, dotted-key data (no imports, no types).
|
|
3
|
+
*
|
|
4
|
+
* Convention: [category].[context].[property?].[variant].[state]
|
|
5
|
+
*
|
|
6
|
+
* GENERATED-STYLE SOURCE: intended to be replaced by the Figma / design-sync export.
|
|
7
|
+
*/
|
|
8
|
+
export const dark = {
|
|
9
|
+
// ── color: page background ────────────────────────────────────────────────
|
|
10
|
+
'color.background': '{palette.neutral.950}',
|
|
11
|
+
|
|
12
|
+
// ── color: surfaces (bg implied — no property segment) ──────────────────
|
|
13
|
+
'color.surface.default': '{palette.neutral.900}',
|
|
14
|
+
'color.surface.raised': '{palette.neutral.800}',
|
|
15
|
+
'color.surface.sunken': '#050506',
|
|
16
|
+
'color.surface.overlay': 'rgba(0, 0, 0, 0.72)',
|
|
17
|
+
'color.surface.accent': '{palette.emerald.500}',
|
|
18
|
+
'color.surface.accent.subtle': '{palette.emerald.950}',
|
|
19
|
+
|
|
20
|
+
// ── color: text / icons (fg implied — no property segment) ──────────────
|
|
21
|
+
'color.text.default': '{palette.neutral.50}',
|
|
22
|
+
'color.text.muted': '{palette.neutral.400}',
|
|
23
|
+
'color.text.subtle': '{palette.neutral.500}',
|
|
24
|
+
'color.text.disabled': '{palette.neutral.700}',
|
|
25
|
+
'color.text.inverse': '{palette.neutral.950}',
|
|
26
|
+
'color.text.link': '{palette.blue.300}',
|
|
27
|
+
'color.text.accent': '{palette.emerald.400}',
|
|
28
|
+
'color.text.on-accent': '{palette.neutral.950}',
|
|
29
|
+
'color.text.on-accent-subtle': '{palette.emerald.300}',
|
|
30
|
+
|
|
31
|
+
// ── color: borders (border-color implied — no property segment) ──────────
|
|
32
|
+
'color.border.subtle': '{palette.neutral.800}',
|
|
33
|
+
'color.border.default': '{palette.neutral.700}',
|
|
34
|
+
'color.border.strong': '{palette.neutral.600}',
|
|
35
|
+
'color.border.focus': '{palette.blue.400}',
|
|
36
|
+
'color.border.accent': '{palette.emerald.500}',
|
|
37
|
+
|
|
38
|
+
// ── color: interactive actions (bg + fg → property required) ────────────
|
|
39
|
+
'color.action.bg.primary': '{palette.emerald.500}',
|
|
40
|
+
'color.action.bg.primary.hover': '{palette.emerald.400}',
|
|
41
|
+
'color.action.bg.primary.active': '{palette.emerald.300}',
|
|
42
|
+
'color.action.bg.primary.disabled': '{palette.slate.700}',
|
|
43
|
+
'color.action.fg.primary': '{palette.slate.950}',
|
|
44
|
+
|
|
45
|
+
'color.action.bg.subtle': '{palette.emerald.950}',
|
|
46
|
+
'color.action.bg.subtle.hover': '{palette.emerald.900}',
|
|
47
|
+
'color.action.bg.subtle.active': '{palette.emerald.800}',
|
|
48
|
+
'color.action.bg.subtle.disabled': '{palette.neutral.900}',
|
|
49
|
+
'color.action.fg.subtle': '{palette.emerald.300}',
|
|
50
|
+
|
|
51
|
+
'color.action.bg.neutral': 'transparent',
|
|
52
|
+
'color.action.bg.neutral.hover': '{palette.neutral.800}',
|
|
53
|
+
'color.action.bg.neutral.active': '{palette.neutral.700}',
|
|
54
|
+
'color.action.bg.neutral.disabled': 'transparent',
|
|
55
|
+
'color.action.fg.neutral': '{palette.neutral.400}',
|
|
56
|
+
|
|
57
|
+
// ── color: status (bg + fg + border → property required) ────────────────
|
|
58
|
+
'color.status.bg.success': '{palette.green.500}',
|
|
59
|
+
'color.status.bg.success.subtle': '{palette.green.900}',
|
|
60
|
+
'color.status.border.success': '{palette.green.700}',
|
|
61
|
+
'color.status.border.success.subtle': '{palette.green.800}',
|
|
62
|
+
'color.status.fg.success': '{palette.slate.950}',
|
|
63
|
+
'color.status.fg.success.subtle': '{palette.green.200}',
|
|
64
|
+
|
|
65
|
+
'color.status.bg.warning': '{palette.amber.400}',
|
|
66
|
+
'color.status.bg.warning.subtle': '{palette.amber.900}',
|
|
67
|
+
'color.status.border.warning': '{palette.amber.700}',
|
|
68
|
+
'color.status.border.warning.subtle': '{palette.amber.800}',
|
|
69
|
+
'color.status.fg.warning': '{palette.slate.950}',
|
|
70
|
+
'color.status.fg.warning.subtle': '{palette.amber.200}',
|
|
71
|
+
|
|
72
|
+
'color.status.bg.danger': '{palette.red.500}',
|
|
73
|
+
'color.status.bg.danger.subtle': '{palette.red.950}',
|
|
74
|
+
'color.status.border.danger': '{palette.red.800}',
|
|
75
|
+
'color.status.border.danger.subtle': '{palette.red.900}',
|
|
76
|
+
'color.status.fg.danger': '{palette.white}',
|
|
77
|
+
'color.status.fg.danger.subtle': '{palette.red.200}',
|
|
78
|
+
|
|
79
|
+
'color.status.bg.info': '{palette.sky.500}',
|
|
80
|
+
'color.status.bg.info.subtle': '{palette.sky.950}',
|
|
81
|
+
'color.status.border.info': '{palette.sky.800}',
|
|
82
|
+
'color.status.border.info.subtle': '{palette.sky.900}',
|
|
83
|
+
'color.status.fg.info': '{palette.slate.950}',
|
|
84
|
+
'color.status.fg.info.subtle': '{palette.sky.200}',
|
|
85
|
+
|
|
86
|
+
// ── elevation: platform-aware shadow + Android elevation ──────────────────
|
|
87
|
+
'elevation.none.shadowColor': '#000000',
|
|
88
|
+
'elevation.none.shadowOpacity': 0,
|
|
89
|
+
'elevation.none.shadowRadius': 0,
|
|
90
|
+
'elevation.none.shadowOffset.width': 0,
|
|
91
|
+
'elevation.none.shadowOffset.height': 0,
|
|
92
|
+
'elevation.none.elevation': 0,
|
|
93
|
+
'elevation.sm.shadowColor': '#000000',
|
|
94
|
+
'elevation.sm.shadowOpacity': 0.3,
|
|
95
|
+
'elevation.sm.shadowRadius': 2,
|
|
96
|
+
'elevation.sm.shadowOffset.width': 0,
|
|
97
|
+
'elevation.sm.shadowOffset.height': 1,
|
|
98
|
+
'elevation.sm.elevation': 1,
|
|
99
|
+
'elevation.md.shadowColor': '#000000',
|
|
100
|
+
'elevation.md.shadowOpacity': 0.4,
|
|
101
|
+
'elevation.md.shadowRadius': 6,
|
|
102
|
+
'elevation.md.shadowOffset.width': 0,
|
|
103
|
+
'elevation.md.shadowOffset.height': 2,
|
|
104
|
+
'elevation.md.elevation': 3,
|
|
105
|
+
'elevation.lg.shadowColor': '#000000',
|
|
106
|
+
'elevation.lg.shadowOpacity': 0.5,
|
|
107
|
+
'elevation.lg.shadowRadius': 12,
|
|
108
|
+
'elevation.lg.shadowOffset.width': 0,
|
|
109
|
+
'elevation.lg.shadowOffset.height': 4,
|
|
110
|
+
'elevation.lg.elevation': 6,
|
|
111
|
+
'elevation.xl.shadowColor': '#000000',
|
|
112
|
+
'elevation.xl.shadowOpacity': 0.6,
|
|
113
|
+
'elevation.xl.shadowRadius': 24,
|
|
114
|
+
'elevation.xl.shadowOffset.width': 0,
|
|
115
|
+
'elevation.xl.shadowOffset.height': 8,
|
|
116
|
+
'elevation.xl.elevation': 12,
|
|
117
|
+
};
|