-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[suggestions] .npmrc and .lint-staged #2
Comments
Great the suggestions!
Sometimes files change (new imports...) without Biome linting. |
Suggestions 1 and 2 (cached) pushed. And also fixed the initialization of Vite with Tamagui thanks to @itsmelion (tamagui/tamagui#2569) |
Great work. 💪 It is that currently you do: ps: I am doing these suggestions, because I'm using your template as reference for a private monorepo I am setting up and because I see the template as a promising alternative to Takeout which is Turbo based. Truth be told, yours does pretty much what I need, but I need to go through the learning curve in order to understand the ecosystem. #i-am-just-a-fullstack-web-dev. :) |
Good explanation! Sometimes Android and iOS set up can be tricky. Check the README guide. I'm very happy this repo helps you. The JS community is very into Turbo (a free product from Vercel) 😔, but Nx is the only product of Nx company. They're constantly improving the open source packages. I suggest you to try the Nx IDE extension, it's really helpful to generate new packages (it takes several tries to get used to it). It also automatically uses the |
Expo team suggests using I opened an issue nrwl/nx#22631. You can make some noise to increase the priority. |
I have another project that uses Clean Architecture. I use Nx extension to generate the structure. My "paths": {
"@xiroi/library/domain": [
"packages/xiroi-bc/library/domain/src/index.ts"
],
"@xiroi/library/infrastructure/database": [
"packages/xiroi-bc/library/infrastructure/database/src/index.ts"
],
"@xiroi/library/infrastructure/graphql": [
"packages/xiroi-bc/library/infrastructure/graphql/src/index.ts"
],
"@xiroi/library/ui/components": [
"packages/xiroi-bc/library/ui/components/src/index.ts"
],
"@xiroi/library/usecases": [
"packages/xiroi-bc/library/usecases/src/index.ts"
],
"@xiroi/shared/domain": [
"packages/xiroi-shared/domain/src/index.ts"
],
"@xiroi/shared/ui/components": [
"packages/xiroi-shared/ui/components/src/index.ts"
],
"@xiroi/shared/ui/core/*": [
"packages/xiroi-shared/ui/core/src/*"
],
"@xiroi/shared/ui/icons": [
"packages/xiroi-shared/ui/icons/src/index.ts"
],
"@xiroi/shared/ui/localization": [
"packages/xiroi-shared/ui/localization/src/index.ts"
],
"@xiroi/shared/usecases": [
"packages/xiroi-shared/usecases/src/index.ts"
],
"@xiroi/ui-pages/library": [
"packages/xiroi-ui-pages/library/src/index.ts"
],
"@xiroi/ui-pages/login": [
"packages/xiroi-ui-pages/login/src/index.ts"
],
"@xiroi/ui-pages/settings": [
"packages/xiroi-ui-pages/settings/src/index.ts"
]
}
... Then each An other very cool Nx feature is the relationship graph of all the packages and apps. You can check the dependencies of the Clean Architecture. |
Hey @guillempuche. Thanks for all the tips! Regarding Tamagui We will certainly apply some of them. However, I came to the decision of not using Tamagui. At some point, I decided to create a small side project just to try the framework more in-depth before going all in on the main project (within the monorepo) and I discovered that I did not like the development experience, as much as I would have expected. We knew Tamagui's learning curve would be intense, pretty much like PandaCSS for web was since it involves design-system concepts and basically provides an opinionated way of achieving a good design-system implementation. However, not only was it intense, but I also ended up not enjoying some architectural decisions and mostly public APIs provided by the lib. Most importantly I felt like the documentation needed lots of "digging" around to find what I wanted and the truth is the application we will be developing won't need all the power Tamagui was going to offer. We ended up opting for something more barebones, closer to the React Native original API, and most importantly less opinionated. That choice was: react-native-unistyles. We will still be able to implement design-system tokens, but we won't be constrained by the learning curve that Tamagui demands without providing (in our opinion) the necessary tools to overcome that curve. Regarding expo We tried using PNPM initially, but failed miserably, because Basically, we are able to create development and debug builds, using
I'll follow this thread. 💪 |
Yes, it isn't easy. Some tips with a simpler than Takeout but ready for Material Design tokens https://m3.material.io/ (except deep concepts like state layers) Config package// packages/config/src/index.ts export * from "./tamagui.config"; // packages/config/src/tamagui.config.ts import { config as configV3 } from "@tamagui/config/v3";
import { createMedia } from "@tamagui/react-native-media-driver";
import { shorthands } from "@tamagui/shorthands";
import {
size,
space,
radius as tamaguiRadius,
themes,
zIndex,
} from "@tamagui/themes/v3-themes";
import { createTamagui, createTokens } from "tamagui";
import { dark } from "@tamagui/themes/types/generated-v2";
import { animations } from "./animations";
import {
palette,
themeDark,
themeDarkContrastMedium,
themeLight,
themeLightContrastHigh,
themeLightContrastMedium,
} from "./colors";
import { fonts } from "./fonts";
import { borderRadius, media } from "./sizes";
export const tamaguiConfig = createTamagui({
...configV3,
...themes,
animations,
defaultFont: "body",
fonts,
media,
shorthands,
themes: {
light: themeLight,
lightContrastMedium: themeLightContrastMedium,
lightContrastHigh: themeLightContrastHigh,
dark: themeDark,
darkContrastMedium: themeDarkContrastMedium,
darkContrastHigh: themeDarkContrastMedium,
},
// List of size, space, and radius values here https://tamagui.dev/docs/intro/tokens.
// Don't include Tamagui colors in the tokens object.
tokens: createTokens({
zIndex,
color: palette,
radius: {
...borderRadius,
...tamaguiRadius,
},
size: {
// ...size,
...size,
},
space,
}),
themeClassNameOnRoot: true,
});
export type Conf = typeof tamaguiConfig;
declare module "tamagui" {
interface TamaguiCustomConfig extends Conf {}
}
// For the compiler to find it in Expo, and NextJS
export default tamaguiConfig; // packages/config/src/colors.ts /**
* Colors and themes from https://www.figma.com/file/ljFUVoXDzf8zvObp8T5osT/Cites?type=design&mode=design&t=cu6CnoAB5T8ryF2B-0
*
* List of token names at https://github.com/material-foundation/material-tokens
*/
export const palette = {
// Primary shades
primary0: "#000000",
primary5: "#00131F",
primary10: "#001E2F",
primary15: "#00293E",
primary20: "#00344D",
primary25: "#00405E",
primary30: "#004C6E",
primary35: "#13587C",
primary40: "#256489",
primary50: "#437DA3",
primary60: "#5E97BE",
primary70: "#79B1DA",
primary80: "#94CDF7",
primary90: "#C9E6FF",
primary95: "#E5F2FF",
primary98: "#F6FAFF",
primary99: "#FCFCFF",
primary100: "#FFFFFF",
// Secondary shades
secondary0: "#000000",
secondary5: "#0F0047",
secondary10: "#190064",
secondary15: "#230C75",
secondary20: "#2E1D7F",
secondary25: "#3A2A8A",
secondary30: "#453796",
secondary35: "#5144A3",
secondary40: "#5D50B0",
secondary50: "#766ACB",
secondary60: "#9084E7",
secondary70: "#AB9FFF",
secondary80: "#C8BFFF",
secondary90: "#E5DEFF",
secondary95: "#F4EEFF",
secondary98: "#FDF8FF",
secondary99: "#FFFBFF",
secondary100: "#FFFFFF",
// Tertiary shades
tertiary0: "#000000",
tertiary5: "#001501",
tertiary10: "#002202",
tertiary15: "#002D04",
tertiary20: "#003906",
tertiary25: "#004609",
tertiary30: "#00530D",
tertiary35: "#0F6017",
tertiary40: "#206C22",
tertiary50: "#3C8639",
tertiary60: "#56A150",
tertiary70: "#70BD68",
tertiary80: "#8AD981",
tertiary90: "#B8F1AD",
tertiary95: "#C9FFBD",
tertiary98: "#ECFFE3",
tertiary99: "#F6FFEF",
tertiary100: "#FFFFFF",
// Error shades
error0: "#000000",
error10: "#410002",
error20: "#690005",
error25: "#7E0007",
error30: "#93000A",
error35: "#A80710",
error40: "#BA1A1A",
error50: "#DE3730",
error60: "#FF5449",
error70: "#FF897D",
error80: "#FFB4AB",
error90: "#FFDAD6",
error95: "#FFEDea",
error98: "#FFF8F7",
error99: "#FFFBFF",
error100: "#FFFFFF",
// Neutral shades
neutral0: "#000000",
neutral5: "#101113",
neutral10: "#1A1C1D",
neutral15: "#242627",
neutral20: "#2F3032",
neutral25: "#3A3B3D",
neutral30: "#464748",
neutral35: "#515254",
neutral40: "#5D5E60",
neutral50: "#767779",
neutral60: "#909092",
neutral70: "#ABABAD",
neutral80: "#C6C6C8",
neutral90: "#E3E2E4",
neutral95: "#F1F0F2",
neutral98: "#FAF9FB",
neutral99: "#FDFCFE",
neutral100: "#FFFFFF",
// Neutral variant shades
neutralVariant0: "#000000",
neutralVariant5: "#0D1115",
neutralVariant10: "#181C20",
neutralVariant15: "#22262A",
neutralVariant20: "#2D3135",
neutralVariant25: "#383C40",
neutralVariant30: "#43474B",
neutralVariant35: "#4F5357",
neutralVariant40: "#5B5F63",
neutralVariant50: "#74777C",
neutralVariant60: "#8D9196",
neutralVariant70: "#A8ABB0",
neutralVariant80: "#C3C7CC",
neutralVariant90: "#DFE3E8",
neutralVariant95: "#EEF1F6",
neutralVariant98: "#F7F9FE",
neutralVariant99: "#FCFCFF",
neutralVariant100: "#FFFFFF",
};
export const themeLight = {
primary: palette.primary30, // Assuming #003B57 is palette.primary30
surfaceTint: "#256489", // Hex value directly as not in provided palette list
onPrimary: palette.primary100,
primaryContainer: "#1E5F83", // Direct hex value
onPrimaryContainer: palette.primary100,
secondary: palette.secondary30, // Assuming #342484 is palette.secondary30
onSecondary: palette.secondary100,
secondaryContainer: "#574AA9", // Direct hex value
onSecondaryContainer: palette.secondary100,
tertiary: palette.tertiary30, // Assuming #004208 is palette.tertiary30
onTertiary: palette.tertiary100,
tertiaryContainer: "#1B681E", // Direct hex value
onTertiaryContainer: palette.tertiary100,
error: palette.error40, // Assuming #BA1A1A is palette.error40
onError: palette.error100,
errorContainer: "#FFDAD6", // Direct hex value
onErrorContainer: "#410002", // Direct hex value
background: "#F8F9FD", // Direct hex value
onBackground: palette.neutral10,
surface: "#F8F9FD", // Direct hex value
onSurface: palette.neutral10,
surfaceVariant: palette.neutralVariant80, // Assuming #DDE3EB is palette.neutralVariant80
onSurfaceVariant: palette.neutralVariant30, // Assuming #41484E is palette.neutralVariant30
outline: "#71787F", // Direct hex value
outlineVariant: "#C0C7CF", // Direct hex value
shadow: palette.primary0,
scrim: palette.primary0,
inverseSurface: palette.neutral20,
inverseOnSurface: palette.neutral95,
inversePrimary: palette.primary80, // Assuming #94CDF7 is palette.primary80
primaryFixed: palette.primary90, // Assuming #C9E6FF is palette.primary90
onPrimaryFixed: palette.primary20, // Assuming #001E2F is palette.primary20
primaryFixedDim: palette.primary80, // Assuming #94CDF7 is palette.primary80
onPrimaryFixedVariant: palette.primary30, // Assuming #004C6E is palette.primary30
secondaryFixed: palette.secondary90, // Assuming #E5DEFF is palette.secondary90
onSecondaryFixed: palette.secondary10, // Assuming #190064 is palette.secondary10
secondaryFixedDim: palette.secondary80, // Assuming #C8BFFF is palette.secondary80
onSecondaryFixedVariant: palette.secondary30, // Assuming #453796 is palette.secondary30
tertiaryFixed: "#A5F69A", // Direct hex value
onTertiaryFixed: palette.tertiary10, // Assuming #002202 is palette.tertiary10
tertiaryFixedDim: "#8AD981", // Direct hex value
onTertiaryFixedVariant: palette.tertiary30, // Assuming #00530D is palette.tertiary30
surfaceDim: "#D9DADD", // Direct hex value
surfaceBright: "#F8F9FD", // Direct hex value
surfaceContainerLowest: palette.primary100,
surfaceContainerLow: "#F2F3F7", // Direct hex value
surfaceContainer: "#EDEEF1", // Direct hex value
surfaceContainerHigh: "#E7E8EB", // Direct hex value
surfaceContainerHighest: "#E1E2E6", // Direct hex value
};
export const themeLightContrastMedium = {
primary: palette.primary30, // Assuming #003B57 is palette.primary30
surfaceTint: "#256489", // Hex value directly as not in provided palette list
onPrimary: palette.primary100,
primaryContainer: "#1E5F83", // Direct hex value
onPrimaryContainer: palette.primary100,
secondary: palette.secondary30, // Assuming #342484 is palette.secondary30
onSecondary: palette.secondary100,
secondaryContainer: "#574AA9", // Direct hex value
onSecondaryContainer: palette.secondary100,
tertiary: palette.tertiary30, // Assuming #004208 is palette.tertiary30
onTertiary: palette.tertiary100,
tertiaryContainer: "#1B681E", // Direct hex value
onTertiaryContainer: palette.tertiary100,
error: "#8C0009", // Direct hex value
onError: palette.error100,
errorContainer: "#DA342E", // Direct hex value
onErrorContainer: palette.error100,
background: "#F8F9FD", // Direct hex value
onBackground: palette.neutral10,
surface: "#F8F9FD", // Direct hex value
onSurface: palette.neutral10,
surfaceVariant: palette.neutralVariant80, // Assuming #DDE3EB is palette.neutralVariant80
onSurfaceVariant: "#3D444A", // Direct hex value
outline: "#596066", // Direct hex value
outlineVariant: "#757B82", // Direct hex value
shadow: palette.primary0,
scrim: palette.primary0,
inverseSurface: palette.neutral20,
inverseOnSurface: palette.neutral95,
inversePrimary: palette.primary80, // Assuming #94CDF7 is palette.primary80
};
export const themeLightContrastHigh = {
primary: "#002539", // Direct hex value
surfaceTint: "#256489", // Direct hex value
onPrimary: palette.primary100,
primaryContainer: "#004768", // Direct hex value
onPrimaryContainer: palette.primary100,
secondary: "#200571", // Direct hex value
onSecondary: palette.secondary100,
secondaryContainer: "#413392", // Direct hex value
onSecondaryContainer: palette.secondary100,
tertiary: "#002903", // Direct hex value
onTertiary: palette.tertiary100,
tertiaryContainer: "#004F0C", // Direct hex value
onTertiaryContainer: palette.tertiary100,
error: "#4E0002", // Direct hex value
onError: palette.error100,
errorContainer: "#8C0009", // Direct hex value
onErrorContainer: palette.error100,
background: "#F8F9FD", // Direct hex value
onBackground: palette.neutral10,
surface: "#F8F9FD", // Direct hex value
onSurface: palette.neutral0, // Assuming #000000 is palette.neutral0
surfaceVariant: palette.neutralVariant80, // Assuming #DDE3EB is palette.neutralVariant80
onSurfaceVariant: "#1E252A", // Direct hex value
outline: "#3D444A", // Direct hex value
outlineVariant: "#3D444A", // Direct hex value
shadow: palette.primary0,
scrim: palette.primary0,
inverseSurface: palette.neutral20,
inverseOnSurface: palette.neutral100,
inversePrimary: "#DCEEFF", // Direct hex value
};
export const themeDark = {
primary: palette.primary80,
surfaceTint: palette.primary80,
onPrimary: "#00344D", // Direct hex value
primaryContainer: "#004464", // Direct hex value
onPrimaryContainer: "#ACDBFF", // Direct hex value
secondary: palette.secondary80,
onSecondary: "#2E1D7F", // Direct hex value
secondaryContainer: "#3E308F", // Direct hex value
onSecondaryContainer: "#D7CFFF", // Direct hex value
tertiary: palette.tertiary80,
onTertiary: "#003906", // Direct hex value
tertiaryContainer: "#004C0B", // Direct hex value
onTertiaryContainer: "#99E98E", // Direct hex value
error: palette.error80,
onError: "#690005", // Direct hex value
errorContainer: "#93000A", // Direct hex value
onErrorContainer: "#FFDAD6",
background: "#111416", // Direct hex value
onBackground: palette.neutral100,
surface: "#111416", // Direct hex value
onSurface: palette.neutral100,
surfaceVariant: palette.neutralVariant30,
onSurfaceVariant: palette.neutralVariant80,
outline: "#8B9198", // Direct hex value
outlineVariant: palette.neutralVariant40,
shadow: palette.primary0,
scrim: palette.primary0,
inverseSurface: palette.neutral100,
inverseOnSurface: palette.neutral20,
inversePrimary: "#256489", // Direct hex value
primaryFixed: palette.primary90,
onPrimaryFixed: "#001E2F", // Direct hex value
primaryFixedDim: palette.primary80,
onPrimaryFixedVariant: "#004C6E", // Direct hex value
secondaryFixed: palette.secondary90,
onSecondaryFixed: "#190064", // Direct hex value
secondaryFixedDim: palette.secondary80,
onSecondaryFixedVariant: palette.secondary30,
tertiaryFixed: "#A5F69A", // Direct hex value
onTertiaryFixed: "#002202", // Direct hex value
tertiaryFixedDim: "#8AD981", // Direct hex value
onTertiaryFixedVariant: "#00530D", // Direct hex value
surfaceDim: "#111416", // Direct hex value
surfaceBright: "#37393C", // Direct hex value
surfaceContainerLowest: "#0C0E11", // Direct hex value
surfaceContainerLow: "#191C1E", // Direct hex value
surfaceContainer: "#1D2022", // Direct hex value
surfaceContainerHigh: "#282A2D", // Direct hex value
surfaceContainerHighest: "#323538", // Direct hex value
};
export const themeDarkContrastMedium = {
primary: "#99D1FB", // Direct hex value
surfaceTint: palette.primary80, // Assuming #94CDF7 is palette.primary80
onPrimary: "#001827", // Direct hex value
primaryContainer: "#5E97BE", // Direct hex value
onPrimaryContainer: palette.primary0, // Assuming #000000 is palette.primary0
secondary: "#CCC4FF", // Direct hex value
onSecondary: "#140056", // Direct hex value
secondaryContainer: "#9084E7", // Direct hex value
onSecondaryContainer: palette.primary0, // Assuming #000000 is palette.primary0
tertiary: "#8EDD84", // Direct hex value
onTertiary: "#001C02", // Direct hex value
tertiaryContainer: "#56A150", // Direct hex value
onTertiaryContainer: palette.primary0, // Assuming #000000 is palette.primary0
error: "#FFBAB1", // Direct hex value
onError: "#370001", // Direct hex value
errorContainer: "#FF5449", // Direct hex value
onErrorContainer: palette.primary0, // Assuming #000000 is palette.primary0
background: "#111416", // Direct hex value
onBackground: palette.neutral100,
surface: "#111416", // Direct hex value
onSurface: "#FAFBFE", // Direct hex value
surfaceVariant: palette.neutralVariant30,
onSurfaceVariant: "#C5CBD3", // Direct hex value
outline: "#9DA4AB", // Direct hex value
outlineVariant: "#7D848B", // Direct hex value
shadow: palette.primary0,
scrim: palette.primary0,
inverseSurface: palette.neutral100,
inverseOnSurface: "#282A2D", // Direct hex value
inversePrimary: "#004D70", // Direct hex value
};
export const themeDarkContrastHigh = {
primary: "#F9FBFF", // Direct hex value
surfaceTint: palette.primary80, // Assuming #94CDF7 is palette.primary80
onPrimary: palette.primary0, // Assuming #000000 is palette.primary0
primaryContainer: "#99D1FB", // Direct hex value
onPrimaryContainer: palette.primary0, // Assuming #000000 is palette.primary0
secondary: "#FEF9FF", // Direct hex value
onSecondary: palette.primary0, // Assuming #000000 is palette.primary0
secondaryContainer: "#CCC4FF", // Direct hex value
onSecondaryContainer: palette.primary0, // Assuming #000000 is palette.primary0
tertiary: "#F1FFE9", // Direct hex value
onTertiary: palette.primary0, // Assuming #000000 is palette.primary0
tertiaryContainer: "#8EDD84", // Direct hex value
onTertiaryContainer: palette.primary0, // Assuming #000000 is palette.primary0
error: "#FFF9F9", // Direct hex value
onError: palette.primary0, // Assuming #000000 is palette.primary0
errorContainer: "#FFBAB1", // Direct hex value
onErrorContainer: palette.primary0, // Assuming #000000 is palette.primary0
background: "#111416", // Direct hex value
onBackground: palette.neutral100,
surface: "#111416", // Direct hex value
onSurface: "#FFFFFF", // Direct hex value
surfaceVariant: palette.neutralVariant30,
onSurfaceVariant: "#F9FBFF", // Direct hex value
outline: "#C5CBD3", // Direct hex value
outlineVariant: "#C5CBD3", // Direct hex value
shadow: palette.primary0,
scrim: palette.primary0,
inverseSurface: palette.neutral100,
inverseOnSurface: palette.primary0, // Assuming #000000 is palette.primary0
inversePrimary: "#002D44", // Direct hex value
}; // packages/config/src/size.ts import { createMedia } from "tamagui";
// For site responsive demo
export const media = createMedia({
xs: { maxWidth: 660 },
gtXs: { minWidth: 660 + 1 },
sm: { maxWidth: 800 },
gtSm: { minWidth: 800 + 1 },
md: { maxWidth: 1020 },
gtMd: { minWidth: 1020 + 1 },
lg: { maxWidth: 1280 },
gtLg: { minWidth: 1280 + 1 },
short: { maxHeight: 820 },
tall: { minHeight: 820 },
// hoverNone: { hover: "none" },
// pointerCoarse: { pointer: "coarse" },
});
// {
// tiny: { maxWidth: 500 },
// gtTiny: { minWidth: 500 + 1 },
// small: { maxWidth: 620 },
// gtSmall: { minWidth: 620 + 1 },
// medium: { maxWidth: 780 },
// gtMedium: { minWidth: 780 + 1 },
// large: { maxWidth: 900 },
// gtLarge: { minWidth: 900 + 1 },
// };
export const borderRadius = {
brSm: 8,
brMd: 16,
brLg: 24,
}; // .../animations.ts import { createAnimations } from "@tamagui/animations-css";
export const animations = createAnimations({
bouncy: "800ms cubic-bezier(0.34, 1.56, 0.64, 1) both",
fast: "ease-in 150ms",
medium: "ease-in 300ms",
slow: "ease-in 450ms",
}); // .../animations.native.ts import { createAnimations } from "@tamagui/animations-react-native";
export const animations = createAnimations({
bouncy: {
type: "spring",
damping: 10,
mass: 0.9,
stiffness: 100,
},
fast: {
damping: 20,
mass: 1.2,
stiffness: 250,
},
medium: {
damping: 10,
mass: 0.9,
stiffness: 100,
},
slow: {
damping: 20,
stiffness: 60,
},
}); // .../fonts.ts import { createInterFont } from "@tamagui/font-inter";
const sans = createInterFont({
// family: 'System',
// size: {},
// transform: {},
// weight: {},
// color: {},
// letterSpacing: {},
face: {
400: { normal: "Inter" },
500: { normal: "Inter" },
700: { normal: "InterBold" },
},
});
const mono = createInterFont(
{
// size: {},
// transform: {},
// weight: {},
// color: {},
// letterSpacing: {},
family:
'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;',
face: {
400: { normal: "Inter" },
500: { normal: "Inter" },
700: { normal: "InterBold" },
},
},
// {
// sizeSize: (size) => Math.round(size * 1.1),
// sizeLineHeight: (size) => Math.round(size * 1.1 + (size > 20 ? 10 : 10)),
// },
);
// Tamagui requires body and heading. More here https://tamagui.dev/docs/core/configuration
export const fonts = {
body: sans,
heading: sans,
mono,
}; Components package// packages/components/tsconfig.json {
"extends": "../../tsconfig.base",
"include": [
"**/*.ts",
"**/*.tsx",
"../config/src/tamagui.config.ts" // I think this helps to import as `tamagui` in the package, but it might be useless.
],
"compilerOptions": {
"composite": true,
"jsx": "react-jsx"
},
"references": []
} // packages/components/src/text.ts /**
* Inspired in https://tamagui.dev/ui/headings and https://github.com/status-im/status-web/blob/main/packages/components/src/text/text.tsx
*/
import type { ReactNode } from "react";
import { SizableText, styled } from "tamagui";
type Props = {
children: ReactNode;
lowercase?: boolean;
select?: false;
truncate?: boolean;
uppercase?: boolean;
wrap?: false;
};
/**
* Text based on Material Design https://m3.material.io/styles/typography/
*/
export const Text = (
{ color = "$onBackground", ...props }: Props,
// ref: Ref<RNText>,
) => {
// const { color = "$onBackground", ref, ...props } = props;
// return <Base {...props} color={color} ref={ref} />;
return <Base {...props} color={color} />;
};
const Base = styled(SizableText, {
name: "Text",
color: "$onBackground",
userSelect: "auto",
whiteSpace: "normal",
variants: {
// "display-l": {
// true: {
// accessibilityRole: "header",
// fontSize: 57,
// fontWeight: "400",
// letterSpacing: -0.25,
// lineHeight: 64,
// role: "heading",
// tag: "h1",
// },
// },
"display-m": {
true: {
accessibilityRole: "header",
fontSize: 45,
fontWeight: "400",
letterSpacing: 0,
lineHeight: 52,
role: "heading",
tag: "h2",
},
},
"display-sm": {
true: {
fontSize: 36,
fontWeight: "400",
letterSpacing: 0,
lineHeight: 44,
},
},
"headline-l": {
true: {
accessibilityRole: "header",
fontSize: 32,
fontWeight: "400",
letterSpacing: 0,
lineHeight: 40,
role: "heading",
tag: "h3",
},
},
"headline-m": {
true: {
accessibilityRole: "header",
fontSize: 28,
fontWeight: "400",
letterSpacing: 0,
lineHeight: 36,
role: "heading",
tag: "h4",
},
},
// "headline-sm": {
// true: {
// fontSize: 24,
// fontWeight: "400",
// letterSpacing: 0,
// lineHeight: 32,
// },
// },
title: {
true: {
accessibilityRole: "header",
fontSize: 22,
fontWeight: "400",
letterSpacing: 0,
lineHeight: 28,
role: "heading",
tag: "h5",
},
},
// "title-m": {
// true: {
// fontSize: 16,
// fontWeight: "500",
// letterSpacing: 0.15,
// lineHeight: 24,
// },
// },
"body-l": {
true: {
fontSize: 16,
fontWeight: "400",
letterSpacing: 0.5,
lineHeight: 24,
tag: "span",
},
},
"body-m": {
true: {
fontSize: 14,
fontWeight: "400",
letterSpacing: 0.25,
lineHeight: 20,
tag: "span",
},
},
"label-l": {
true: {
fontSize: 14,
fontWeight: "500",
letterSpacing: 0.1,
lineHeight: 20,
tag: "span",
},
},
"label-m": {
true: {
fontSize: 12,
fontWeight: "500",
letterSpacing: 0.5,
lineHeight: 16,
},
},
bold: {
true: {
fontWeight: "700",
},
},
lowercase: {
true: {
textTransform: "lowercase",
},
},
uppercase: {
true: {
textTransform: "uppercase",
},
},
wrap: {
false: {
whiteSpace: "nowrap",
},
},
truncate: {
true: {
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
wordWrap: "normal",
maxWidth: "100%",
minWidth: 0,
},
},
// select: {
// false: {
// userSelect: "none",
// },
// },
} as const,
defaultVariants: {
"body-l": true,
},
});
// const _Text = forwardRef(Text);
// export { _Text as Text };
// export type { Props as TextProps }; // packages/components/src/button.tsx /**
* Inspired in https://tamagui.dev/bento/elements/buttons
*/
import type { ReactNode } from "react";
import { cloneElement } from "react";
import {
AnimatePresence,
Button as ButtonTamagui,
Spinner,
styled,
} from "tamagui";
/**
* ButtonText based on [Material Design](https://m3.material.io/styles/typography/)
*/
export const ButtonText = ({
children,
fullWidth,
icon,
loading,
...props
}: {
children: string;
fullWidth?: boolean;
icon?: ReactNode;
loading?: boolean;
}) => {
// export const ButtonText = (props: Props, ref: Ref<View>) => {
return (
<Base
{...props}
pl={icon || loading ? 16 : 24} // TODO: support RTL
pr={24}
// ref={ref}
// width={fullWidth ? "100%" : "auto"}
>
{loading ? (
<AnimatePresence>
<ButtonTamagui.Icon>
<Spinner
animation="bouncy"
enterStyle={{
scale: 0,
}}
exitStyle={{
scale: 0,
}}
/>
</ButtonTamagui.Icon>
</AnimatePresence>
) : null}
{icon && !loading ? (
<ButtonTamagui.Icon>
{cloneElement(icon, {
size: 18,
})}
</ButtonTamagui.Icon>
) : null}
<ButtonTamagui.Text>{children}</ButtonTamagui.Text>
</Base>
);
};
// It doesn't use the same values as in Material Desing guideline because it
// doesn't have the state layer.
const Base = styled(ButtonTamagui, {
name: "ButtonText",
br: "$6",
userSelect: "none",
size: 40,
variants: {
filled: {
true: {
bc: "$primary",
color: "$onPrimary",
hoverStyle: {
bc: "$primary",
opacity: 0.88,
},
pressStyle: {
bc: "$primary",
opacity: 0.76,
},
},
},
"filled-disabled": {
true: {
bc: "$onSurface",
color: "$surface",
opacity: 0.12,
pointerEvents: "none",
},
},
outlined: {
true: {
bc: "transparent",
borderWidth: 1,
borderColor: "$primary",
color: "$primary",
hoverStyle: { bc: "$surfaceContainer" },
pressStyle: { bc: "$surfaceContainerHigh" },
},
},
"outlined-disabled": {
true: {
bc: "transparent",
borderWidth: 1,
borderColor: "$surfaceContainerHighest",
color: "$surfaceContainerHighest",
pointerEvents: "none",
},
},
text: {
true: {
bc: "transparent",
color: "$primary",
hoverStyle: { bc: "$surfaceContainerHigh" },
pressStyle: { bc: "$surfaceContainerHighest" },
},
},
"text-disabled": {
true: {
bc: "transparent",
color: "$onSurface",
opacity: 0.12,
pointerEvents: "none",
},
},
} as const,
defaultVariants: {
text: true,
},
}); NextJSYou don't need to create // next.config.js /** @type {import('next').NextConfig} */
const { withTamagui } = require("@tamagui/next-plugin");
const { join } = require("path");
const boolVals = {
true: true,
false: false,
};
const disableExtraction =
boolVals[process.env.DISABLE_EXTRACTION] ??
process.env.NODE_ENV === "development";
console.log(`
Welcome to Tamagui!
You can update this monorepo to the latest Tamagui release just by running:
yarn upgrade:tamagui
We've set up a few things for you.
See the "excludeReactNativeWebExports" setting in next.config.js, which omits these
from the bundle: Switch, ProgressBar Picker, CheckBox, Touchable. To save more,
you can add ones you don't need like: AnimatedFlatList, FlatList, SectionList,
VirtualizedList, VirtualizedSectionList.
🐣
Remove this log in next.config.js.
`);
const plugins = [
withTamagui({
config: "../../packages/config/src/tamagui.config.ts",
components: ["tamagui", "@my/ui"],
importsWhitelist: ["constants.js", "colors.js"],
outputCSS:
process.env.NODE_ENV === "production" ? "./public/tamagui.css" : null,
logTimings: true,
disableExtraction,
shouldExtract: (path) => {
if (path.includes(join("packages", "app"))) {
return true;
}
},
excludeReactNativeWebExports: [
"Switch",
"ProgressBar",
"Picker",
"CheckBox",
"Touchable",
],
}),
];
module.exports = () => {
/** @type {import('next').NextConfig} */
let config = {
typescript: {
ignoreBuildErrors: true,
},
modularizeImports: {
"@tamagui/lucide-icons": {
transform: `@tamagui/lucide-icons/dist/esm/icons/{{kebabCase member}}`,
skipDefaultConversion: true,
},
},
transpilePackages: [
"solito",
"react-native-web",
"expo-linking",
"expo-constants",
"expo-modules-core",
],
experimental: {
scrollRestoration: true,
},
};
for (const plugin of plugins) {
config = {
...config,
...plugin(config),
};
}
return config;
}; |
Yes, PNPM or Yarn in symlink mode (no real I don't know PNPM, but Yarn 4 has PnP (aka symlinks) by default, you need to disable in // .yarnrc.yml enableGlobalCache: false
enableTelemetry: false
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.1.1.cjs |
I'm pretty new to
nx
andyarn berry
, but here are two suggestions:Suggestion #1:
.npmrc
is ignored, so perhaps you don't need to keep it in the template?Suggestion #2:
eslint
routines for languages/meta-frameworks not yet supported by Biome, but eslint provides a very good--cache
option which pretty much does what link-staged does.nx affected
tbh) or --staged to the commands which does exactly what lint-staged does.eslint --cache
andbiome --changed
The text was updated successfully, but these errors were encountered: