@yahoo/uds 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. package/cli/README.md +78 -131
  2. package/cli/commands/purge.ts +7 -3
  3. package/cli/env.d.ts +1 -0
  4. package/cli/utils/purgeCSS.test.ts +43 -3
  5. package/cli/utils/purgeCSS.ts +100 -14
  6. package/dist/Image.native-B3I4JoH3.d.cts +38 -0
  7. package/dist/Image.native-DUAFJodS.d.ts +38 -0
  8. package/dist/VStack-BHlRUsOR.d.cts +103 -0
  9. package/dist/VStack-DMb_RGRS.d.ts +103 -0
  10. package/dist/experimental/index.cjs +1 -1
  11. package/dist/experimental/index.d.cts +8 -8
  12. package/dist/experimental/index.d.ts +8 -8
  13. package/dist/experimental/index.js +1 -1
  14. package/dist/experimental/index.native.cjs +1 -1
  15. package/dist/experimental/index.native.d.cts +3 -3
  16. package/dist/experimental/index.native.d.ts +3 -3
  17. package/dist/experimental/index.native.js +1 -1
  18. package/dist/fixtures.cjs +1990 -0
  19. package/dist/fixtures.d.ts +81 -0
  20. package/dist/fixtures.js +1954 -0
  21. package/dist/index.cjs +1 -1
  22. package/dist/index.d.cts +42 -237
  23. package/dist/index.d.ts +42 -237
  24. package/dist/index.js +1 -1
  25. package/dist/{index.native-CisPq4BI.d.ts → index.native-BTfOSmUx.d.ts} +1 -1
  26. package/dist/{index.native-DJlx-bfM.d.cts → index.native-Bm-r2Dpa.d.cts} +1 -1
  27. package/dist/index.native.cjs +1 -1
  28. package/dist/index.native.d.cts +21 -84
  29. package/dist/index.native.d.ts +21 -84
  30. package/dist/index.native.js +1 -1
  31. package/dist/styles/globals.css +0 -1
  32. package/dist/styles/toast.css +1 -0
  33. package/dist/styles/toast.d.cts +2 -0
  34. package/dist/styles/toast.d.ts +2 -0
  35. package/dist/tailwindPlugin.cjs +1 -1
  36. package/dist/tailwindPlugin.d.cts +8 -2
  37. package/dist/tailwindPlugin.d.ts +8 -2
  38. package/dist/tailwindPlugin.js +1 -1
  39. package/dist/tailwindPurge.cjs +1 -1
  40. package/dist/tailwindPurge.js +1 -1
  41. package/dist/tokens/index.cjs +1 -1
  42. package/dist/tokens/index.d.cts +8 -3
  43. package/dist/tokens/index.d.ts +8 -3
  44. package/dist/tokens/index.js +1 -1
  45. package/dist/tokens/index.native.cjs +1 -1
  46. package/dist/tokens/index.native.d.cts +2 -2
  47. package/dist/tokens/index.native.d.ts +2 -2
  48. package/dist/tokens/index.native.js +1 -1
  49. package/dist/tokens/parseTokens.cjs +1 -1
  50. package/dist/tokens/parseTokens.d.cts +8 -18
  51. package/dist/tokens/parseTokens.d.ts +8 -18
  52. package/dist/tokens/parseTokens.js +1 -1
  53. package/dist/tokens/parseTokens.native.cjs +1 -1
  54. package/dist/tokens/parseTokens.native.d.cts +4 -21
  55. package/dist/tokens/parseTokens.native.d.ts +4 -21
  56. package/dist/tokens/parseTokens.native.js +1 -1
  57. package/dist/{types-CzJpH_Oi.d.cts → types-COiuE8XK.d.cts} +49 -138
  58. package/dist/{types-CzJpH_Oi.d.ts → types-COiuE8XK.d.ts} +49 -138
  59. package/package.json +14 -13
  60. package/dist/Image.native-C6kOWgnf.d.ts +0 -38
  61. package/dist/Image.native-VeXt5aeI.d.cts +0 -38
  62. package/dist/VStack-BSD9TbBd.d.cts +0 -114
  63. package/dist/VStack-Dk3-8IyU.d.ts +0 -114
  64. package/dist/fixtures/index.cjs +0 -1
  65. package/dist/fixtures/index.d.cts +0 -154
  66. package/dist/fixtures/index.d.ts +0 -154
  67. package/dist/fixtures/index.js +0 -1
package/cli/README.md CHANGED
@@ -1,181 +1,128 @@
1
+ import { Box } from '@yahoo/uds';
2
+ import { RequiredChip } from '~/components/RequiredChip';
3
+ import { DocImage } from '~/components/DocImage';
4
+
1
5
  # Universal CLI
2
6
 
3
- We leverage Bluebun, which is a CLI framework inspired by [Gluegun](https://github.com/infinitered/gluegun), but specifically designed to be used with [Bun](https://bun.sh), the new JS runtime.
7
+ > **Early preview notice**: The CLI tool currently requires Bun. This requirement may change in the future but you will need to install and use Bun locally to use the `uds` command.
4
8
 
5
- Bluebun relies on Bun APIs and is designed to be extremely fast, with no-dependencies.
9
+ The Universal CLI is available as command, `uds`. The tool was created with [Bluebun](https://github.com/jamonholmgren/bluebun/) (inspired by [Gluegun](https://github.com/infinitered/gluegun)), but is specifically designed to be used with [Bun](https://bun.sh). Bluebun relies on Bun APIs and is designed to be extremely fast, with no-dependencies.
6
10
 
7
- > Trying to add a new command? Please see the "Adding a Command" section below
11
+ <Box justifyContent="center">
12
+ <DocImage light={{ src: '/images/cli-screenshot.png', width: 500, height: 356 }} />
13
+ </Box>
8
14
 
9
- # Commands
15
+ ## Requirements
10
16
 
11
- > Please note: If you are _not_ running the CLI from a package.json script you will need to add `bun` before the binary in order to run it directly. i.e. `bun uds purge`
17
+ 1. To use the CLI, first [install](/docs/getting-started/quick-start#installation) the `@yahoo/uds` package as a dependency in your package.json. This makes the tool available in your repo.
12
18
 
13
- In any consumer of `@yahoo/uds` the following commands are available:
19
+ - Install Bun if you don't already have it:
14
20
 
15
- ## Config
21
+ ```bash
22
+ curl -fsSL https://bun.sh/install | bash
23
+ ```
16
24
 
17
- ### Using args
25
+ ## Commands
18
26
 
19
- | Arg | Required | Default |
20
- | ------- | -------- | --------------- |
21
- | id | true | |
22
- | outFile | false | ./uds.config.ts |
27
+ > **Note**: If you are _not_ running the CLI from a package.json script you will need to add `bun` before the binary in order to run it directly. i.e. `bun uds purge`
23
28
 
24
- ```shell
25
- uds sync --id [id] --outFile [path]
29
+ The following command are available after installing `@yahoo/uds`:
26
30
 
27
- uds sync --id [id]
28
- ```
31
+ ### Sync
29
32
 
30
- ### Using ENV vars
33
+ The `uds sync` command fetches the latest design config from the [Configurator](/docs/getting-started/using-configurator) and writes it to a file in your project.
31
34
 
32
- | Env Var | Required | Default |
33
- | ------------ | -------- | --------------- |
34
- | UDS_ID | true | |
35
- | UDS_OUT_FILE | false | ./uds.config.ts |
35
+ #### Flags
36
36
 
37
- ```shell
38
- UDS_ID=[id] UDS_OUT_FILE=[path] uds sync
39
- ```
37
+ | Flag | Description | Default | Required |
38
+ | --------- | --------------------------- | --------------- | ---------------- |
39
+ | `id` | ID from the Configurator | | <RequiredChip /> |
40
+ | `outFile` | File to write the output to | ./uds.config.ts | |
40
41
 
41
- ## Expo
42
+ **Example:**
42
43
 
43
44
  ```shell
44
- uds expo build --profile [profile] --platform [ios|android]
45
- uds expo dev --profile [profile] --platform [ios|android]
46
- uds expo launch --profile [profile] --platform [ios|android]
47
- uds expo update --profile [profile] --platform [ios|android]
48
- uds expo --help
49
- ```
50
-
51
- ## Purge CSS
52
-
53
- ```shell
54
- uds purge
45
+ uds sync --id [id] --outFile [path]
46
+ uds sync --id [id]
55
47
  ```
56
48
 
57
- ## Adding a command
49
+ #### Enviornment variables
58
50
 
59
- > Please note: Adding nested commands, i.e. uds expo dev, appears to not work correctly when UDS is consumed from npm. As a workaround, please see code for expo/expo.ts for re-routing sub-commands from the root command file. To verify your CLI command works correctly you should run `npm pack` within the packages/uds directory. Once you have your generated tarball you should copy that tarball to a test application such as https://github.com/yahoo-design/uds-nextjs-demo, then add `"@yahoo/uds": "file:./tarball-generated-from-npm-pack.tgz` to it's dependencies and run an install. Now you should be able to run `bun uds [your command name]` to test your functionality.
51
+ Alternatively, you can use environment variables instead of flags.
60
52
 
61
- Commands are organized in a tree structure. The root command is the name of the CLI (uds), and then we can have subcommands under that, and subcommands under those, and so on.
53
+ | Variable | Description | Default | Required |
54
+ | -------------- | --------------------------- | --------------- | ---------------- |
55
+ | `UDS_ID` | ID from the Configurator | | <RequiredChip /> |
56
+ | `UDS_OUT_FILE` | File to write the output to | ./uds.config.ts | |
62
57
 
63
- For example, a command structure might look like this:
58
+ **Example:**
64
59
 
60
+ ```shell
61
+ UDS_ID=[id] UDS_OUT_FILE=[path] uds sync
65
62
  ```
66
- cli/
67
- commands/
68
- pizza.ts # pizza
69
- help.ts # pizza help
70
- bake/
71
- bake.ts # pizza bake
72
- cheese.ts # pizza bake cheese
73
- pepperoni.ts # pizza bake pepperoni
74
- ```
75
63
 
76
- ## Command files
64
+ ### Purge
65
+
66
+ The `uds purge` command is used to optimize and reduce the amount of CSS produced by your app.
77
67
 
78
- Commands are exported as defaults from each command file. They look like this:
68
+ Running this command produces a `./dist/safelist.ts` file in the root of your project. This file imported in your `tailwind.config.js` and passed to the `safelist` configuration option.
79
69
 
80
70
  ```typescript
81
- import { type Props } from 'bluebun';
82
-
83
- export default {
84
- name: 'bake',
85
- description: 'Bake a pizza',
86
- alias: ['b'],
87
- run: async (props: Props) => {
88
- // bake it!
89
- },
71
+ /** @type {import('tailwindcss').Config} */
72
+ const { safelist } = require(`${__dirname}/dist/safelist.ts`);
73
+
74
+ module.exports = {
75
+ content: ['./pages/**/*.{html,jsx,tsx}', './components/**/*.{html,jsx,tsx}'],
76
+ safelist,
77
+ // ...
90
78
  };
91
79
  ```
92
80
 
93
- ## Command properties
94
-
95
- Commands have the following properties:
81
+ For more information about safelisting classes in Tailwind, visit the [official documentation](https://tailwindcss.com/docs/content-configuration#safelisting-classes)
96
82
 
97
- - `name` - the name of the command
98
- - `description` - a description of the command for the automatic help system
99
- - `alias` - an array of aliases for the command (can also be a single string)
100
- - `run` - the function that is run when the command is run, usually `async`
83
+ **Example:**
101
84
 
102
- ## Props
103
-
104
- The `run` function is passed a `Props` object. This object contains the command path, the arguments, and the options, as well as a few other useful things.
85
+ ```shell
86
+ uds purge
87
+ ```
105
88
 
106
- Here are the properties available on the `props` object if we were to run `uds bake cheese convection --sliced --temp=400 --time 30`:
89
+ #### Enviornment variables
107
90
 
108
- - `name` - the name of the CLI (uds)
109
- - `cliPath` - the path to the CLI (./uds-cli)
110
- - `argv` - the raw arguments passed to the CLI (e.g. `["/bin/bun", "/bin/uds", "bake", "cheese", "convection", "--sliced", "--temp=400", "--time", "30"]`)
111
- - `commandPath` - the path to the command that was run (e.g. `["bake", "cheese"]`)
112
- - `arguments` - the positional arguments passed to the command (e.g. `["convection"]`)
113
- - `options` - the options passed to the command (e.g. `{ sliced: true, temp: 400, time: 30 }`)
114
- - `first` - the first argument passed to the command (e.g. `"convection"`)
115
- - `second` - the second argument passed to the command (e.g. `undefined`)
116
- - `third` - the third argument passed to the command (e.g. `undefined`)
91
+ | Variable | Description | Default | Required |
92
+ | ------------------------------- | ------------------------------------------- | ------- | -------- |
93
+ | `ENABLED_SCALE_AND_COLOR_MODES` | Selects which color and scale modes to keep | all | |
117
94
 
118
- Given these props, we might have a command that looks like this:
95
+ **Example:**
119
96
 
120
- ```typescript
121
- import { type Props, spinStart, spinStop } from 'bluebun';
122
- import { createPizza, slice } from './_pizza';
123
- import { convectionBake, toasterBake, regularBake } from './_bakePizza';
124
-
125
- export default {
126
- name: 'bake',
127
- description: 'Bake a pizza',
128
- alias: ['b'],
129
- run: async (props: Props) => {
130
- const { first, second, third, options } = props;
131
-
132
- const pizza = createPizza();
133
-
134
- spinStart('Baking pizza...');
135
- if (first === 'convection') {
136
- await convectionBake(pizza, options.temp, options.time);
137
- } else if (first === 'toaster') {
138
- await toasterBake(pizza, options.temp, options.time);
139
- } else {
140
- await regularBake(pizza, options.temp, options.time);
141
- }
142
- spinStop('✅ Pizza baked!');
143
-
144
- spinStart('Slicing pizza...');
145
- if (options.sliced) {
146
- await slice(pizza);
147
- }
148
- spinStop('✅ Pizza sliced!');
149
- },
150
- };
97
+ ```shell
98
+ ENABLED_SCALE_AND_COLOR_MODES="dark,large" uds purge
151
99
  ```
152
100
 
153
- # Reference
101
+ ### Expo (WIP)
154
102
 
155
- Bluebun comes with a number of built-in utilities that are useful. They're all exported from `bluebun` directly, so you can import them like this:
103
+ The `uds expo` command is for building and launching React Native apps using Expo.
104
+ This command is still a WIP and is only used internally at the moment.
156
105
 
157
- ```typescript
158
- import { inputKey } from 'bluebun';
106
+ ```shell
107
+ uds expo build --profile [profile] --platform [ios|android]
108
+ uds expo dev --profile [profile] --platform [ios|android]
109
+ uds expo launch --profile [profile] --platform [ios|android]
110
+ uds expo update --profile [profile] --platform [ios|android]
111
+ uds expo --help
159
112
  ```
160
113
 
161
- Each of the following docs has usage examples and a Testing section that gives examples on how to write tests for them.
114
+ ## Development
115
+
116
+ The CLI is created with [Bluebun](https://github.com/jamonholmgren/bluebun/) (inspired by [Gluegun](https://github.com/infinitered/gluegun)), but specifically designed to be used with [Bun](https://bun.sh). Bluebun relies on Bun APIs and is designed to be extremely fast, with no-dependencies.
162
117
 
163
- ## CLI
118
+ ### Adding a command
164
119
 
165
- - [run](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/run.md) - run the CLI and command
166
- - [cli](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/cli.md) - start the CLI without running the command
167
- - [commandHelp](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/commandHelp.md) - get a list of all commands and their descriptions
120
+ Commands are organized in a tree structure in `uds/cli/commands`. The root command is the name of the CLI (`uds`) and in `uds.ts`, which subcommand being in its own file. See the Bluebun [Command docs](https://github.com/jamonholmgren/bluebun/blob/main/docs/commands.md) for more information on usage docs and creating command files.
168
121
 
169
- ## User Interaction
122
+ **Important note:**
170
123
 
171
- - [ask](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/ask.md) - ask the user a question via a prompt
172
- - [cursor](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/cursor.md) - manipulate the cursor
173
- - [inputKey](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/inputKey.md) - wait for a single keypress
174
- - [inputKeys](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/inputKeys.md) - wait for and handle multiple keypresses
124
+ Adding nested commands, i.e. `uds expo dev` does work correctly when UDS is consumed from npm. As a workaround, please see code for expo/expo.ts for re-routing sub-commands from the root command file. To verify your CLI command works correctly you should run `npm pack` within the packages/uds directory. Once you have your generated tarball you should copy that tarball to a test application such as https://github.com/yahoo-design/uds-nextjs-demo, then add `"@yahoo/uds": "file:./tarball-generated-from-npm-pack.tgz` to it's dependencies and run an install. Now you should be able to run `bun uds [your command name]` to test your functionality.
175
125
 
176
- ## Output
126
+ ### API Reference
177
127
 
178
- - [print](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/print.md) - print a string to the terminal
179
- - [spinner](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/spinner.md) - start and stop a spinner
180
- - [progress](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/progress.md) - start, update, and stop a progress bar
181
- - [styles and colors](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference/styles.md) - style and colorize text
128
+ Bluebun comes with a number of built-in utilities that are exported from the main `bluebun` package. See [reference guide](https://github.com/jamonholmgren/bluebun/blob/main/docs/reference.md) for more.
@@ -1,15 +1,19 @@
1
1
  import { Props, spinStart, spinStop } from 'bluebun';
2
2
 
3
- import { purge } from '../utils/purgeCSS';
3
+ import { purge, PurgeOptions } from '../utils/purgeCSS';
4
+
5
+ interface PurgeProps extends Props {
6
+ options: PurgeOptions;
7
+ }
4
8
 
5
9
  export default {
6
10
  name: 'purge',
7
11
  description: `Purge unused CSS`,
8
12
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
- run: async (props: Props) => {
13
+ run: async (props: PurgeProps) => {
10
14
  spinStart('Purging css...');
11
15
 
12
- await purge();
16
+ await purge(props.options);
13
17
 
14
18
  spinStop('✅', 'Purging css done!');
15
19
  },
package/cli/env.d.ts CHANGED
@@ -14,5 +14,6 @@ declare module 'bun' {
14
14
  EXPO_USE_METRO_WORKSPACE_ROOT?: string;
15
15
  EXPO_BUNDLE_APP?: string;
16
16
  ESLINT_USE_FLAT_CONFIG?: string;
17
+ ENABLED_SCALE_AND_COLOR_MODES?: string;
17
18
  }
18
19
  }
@@ -1,7 +1,9 @@
1
+ import { defaultTokensConfig } from '@yahoo/uds/tokens';
1
2
  import { describe, expect, it } from 'bun:test';
2
3
  import { Project } from 'ts-morph';
3
4
 
4
5
  import {
6
+ getClassesForEnabledThemesAndScales,
5
7
  getComponentsToConvertToTW,
6
8
  getFiles,
7
9
  getTailwindSafelist,
@@ -87,9 +89,29 @@ describe('purgeCSS', () => {
87
89
  it('returns the tailwind classes corresponding to the props on a component', () => {
88
90
  const res = getTailwindSafelist(project, IMPORTED_UDS_COMPONENTS);
89
91
 
90
- expect(res).toEqual(
91
- 'container fill items-start items-end items-center items-stretch items-baseline justify-start justify-end justify-center justify-between justify-around justify-evenly text-accent text-alert text-black text-brand text-positive text-warning text-white ',
92
- );
92
+ expect(res).toEqual([
93
+ 'container',
94
+ 'fill',
95
+ '',
96
+ 'items-start',
97
+ 'items-end',
98
+ 'items-center',
99
+ 'items-stretch',
100
+ 'items-baseline',
101
+ 'justify-start',
102
+ 'justify-end',
103
+ 'justify-center',
104
+ 'justify-between',
105
+ 'justify-around',
106
+ 'justify-evenly',
107
+ 'text-accent',
108
+ 'text-alert',
109
+ 'text-black',
110
+ 'text-brand',
111
+ 'text-positive',
112
+ 'text-warning',
113
+ 'text-white',
114
+ ]);
93
115
  });
94
116
  });
95
117
 
@@ -136,4 +158,22 @@ describe('purgeCSS', () => {
136
158
  ]);
137
159
  });
138
160
  });
161
+
162
+ describe('getClassesForEnabledThemesAndScales', () => {
163
+ it('returns the list of classes related to the mode/themes we have in the config', () => {
164
+ const classes = getClassesForEnabledThemesAndScales(defaultTokensConfig);
165
+
166
+ expect(classes).toEqual([
167
+ 'uds-color-mode-light',
168
+ 'uds-color-mode-dark',
169
+ 'uds-scale-mode-xsmall',
170
+ 'uds-scale-mode-small',
171
+ 'uds-scale-mode-medium',
172
+ 'uds-scale-mode-large',
173
+ 'uds-scale-mode-xlarge',
174
+ 'uds-scale-mode-xxlarge',
175
+ 'uds-scale-mode-xxxlarge',
176
+ ]);
177
+ });
178
+ });
139
179
  });
@@ -11,16 +11,45 @@ import {
11
11
  findReferencesAsJsxElements,
12
12
  getUsedPropsInReference,
13
13
  } from '@yahoo/uds/tailwindPurge/utils';
14
- import { spinStart } from 'bluebun';
14
+ import {
15
+ ColorModeConfig,
16
+ DARK_COLOR_MODE_CLASSNAME,
17
+ LARGE_SCALE_MODE_CLASSNAME,
18
+ LIGHT_COLOR_MODE_CLASSNAME,
19
+ MEDIUM_SCALE_MODE_CLASSNAME,
20
+ ScaleModeConfig,
21
+ SMALL_SCALE_MODE_CLASSNAME,
22
+ UniversalTokensConfig,
23
+ XLARGE_SCALE_MODE_CLASSNAME,
24
+ XSMALL_SCALE_MODE_CLASSNAME,
25
+ XXLARGE_SCALE_MODE_CLASSNAME,
26
+ XXXLARGE_SCALE_MODE_CLASSNAME,
27
+ } from '@yahoo/uds/tokens';
28
+ import { print, spinStart, spinStop } from 'bluebun';
15
29
  import FastGlob from 'fast-glob';
16
30
  import { JsxOpeningElement, JsxSelfClosingElement, Project, ts } from 'ts-morph';
17
31
 
18
- type SafeList = string;
32
+ const scaleModeToClass: { [key in keyof ScaleModeConfig]: string } = {
33
+ large: LARGE_SCALE_MODE_CLASSNAME,
34
+ medium: MEDIUM_SCALE_MODE_CLASSNAME,
35
+ small: SMALL_SCALE_MODE_CLASSNAME,
36
+ xLarge: XLARGE_SCALE_MODE_CLASSNAME,
37
+ xSmall: XSMALL_SCALE_MODE_CLASSNAME,
38
+ xxLarge: XXLARGE_SCALE_MODE_CLASSNAME,
39
+ xxxLarge: XXXLARGE_SCALE_MODE_CLASSNAME,
40
+ };
41
+
42
+ const colorModeToClass: { [key in keyof ColorModeConfig]: string } = {
43
+ dark: DARK_COLOR_MODE_CLASSNAME,
44
+ light: LIGHT_COLOR_MODE_CLASSNAME,
45
+ };
46
+
47
+ type SafeList = string[];
19
48
  type ImportsList = string[];
20
49
  type Files = string[];
21
50
 
22
51
  // TODO: use CLI args to power the output file path
23
- const OUTPUT_FILE_PATH = Bun.file(`${Bun.env.PWD}/dist/safelist.js`);
52
+ const OUTPUT_FILE_PATH = Bun.file(`${Bun.env.PWD}/dist/safelist.ts`);
24
53
 
25
54
  export const getFiles = async (): Promise<Files> => {
26
55
  const workspaceDir = Bun.env.PWD;
@@ -75,7 +104,10 @@ export const parseFiles = (project: Project, files: Files): ImportsList => {
75
104
  sourceFile
76
105
  ?.getImportDeclarations()
77
106
  .filter((declaration) => {
78
- return declaration.getModuleSpecifier().getText().includes('@yahoo/uds');
107
+ return (
108
+ declaration.getModuleSpecifier().getText().includes('@yahoo/uds') ||
109
+ declaration.getModuleSpecifier().getText().includes('@yahoo/uds/experimental')
110
+ );
79
111
  })
80
112
  .map((declaration) => {
81
113
  return declaration.getNamedImports().map((namedImport) => namedImport.getName());
@@ -96,7 +128,7 @@ export const parseFiles = (project: Project, files: Files): ImportsList => {
96
128
  };
97
129
 
98
130
  export const getTailwindSafelist = (project: Project, componentList: string[]): SafeList => {
99
- let safeList: SafeList = '';
131
+ const safeList: SafeList = [];
100
132
  const validVariants = new Set<string>(variantsList);
101
133
  const usedProps = new Set<string>();
102
134
  componentList.forEach((component: string) => {
@@ -119,13 +151,14 @@ export const getTailwindSafelist = (project: Project, componentList: string[]):
119
151
  });
120
152
 
121
153
  // get the inline TW classes used in each component
122
- safeList += `${componentToTwClasses[component]} `;
154
+ safeList.push(...componentToTwClasses[component].replaceAll('\\', '').split(' '));
123
155
  }
124
156
  });
125
157
 
126
158
  for (const prop of usedProps) {
127
- safeList += `${variantToTailwindClass[prop]} `;
159
+ safeList.push(...variantToTailwindClass[prop].replaceAll('\\', '').split(' '));
128
160
  }
161
+
129
162
  return safeList;
130
163
  };
131
164
 
@@ -136,7 +169,10 @@ export const getTailwindSafelist = (project: Project, componentList: string[]):
136
169
  * const usedProps = getUsedProps(project, 'HStack');
137
170
  */
138
171
  export const getUsedProps = (project: Project, component: string) => {
139
- const references = findNamedImportReferences(project, '@yahoo/uds', component);
172
+ const references: (JsxOpeningElement | JsxSelfClosingElement)[] = [];
173
+ references.push(...findNamedImportReferences(project, '@yahoo/uds', component));
174
+ references.push(...findNamedImportReferences(project, '@yahoo/uds/experimental', component));
175
+
140
176
  // for each reference find the used/references props
141
177
  const usedProps = references.map((reference) => getUsedPropsInReference(reference)).flat();
142
178
 
@@ -152,7 +188,7 @@ const saveToFile = async (safeList: SafeList) => {
152
188
  //! This file is generated by purgeCSS.ts from @yahoo/uds
153
189
  //! Do not edit directly
154
190
  //! If there is issue with this file please report to #ask-uds
155
- const safeList = "${safeList}";
191
+ export const safelist = ${JSON.stringify(safeList)};
156
192
  `;
157
193
 
158
194
  await Bun.write(OUTPUT_FILE_PATH, fileContent);
@@ -177,24 +213,74 @@ export const getComponentsToConvertToTW = (udsImport: ImportsList): string[] =>
177
213
  return Array.from(set) as string[];
178
214
  };
179
215
 
180
- async function purge() {
216
+ /**
217
+ * Get the classes that corresponds to the used modes
218
+ */
219
+ export const getClassesForEnabledThemesAndScales = (config: UniversalTokensConfig): string[] => {
220
+ const classes: string[] = [];
221
+
222
+ // TODO: Remove this once the config supports toggling colorModes and scaleModes
223
+ if (Bun.env.ENABLED_SCALE_AND_COLOR_MODES) {
224
+ Bun.env.ENABLED_SCALE_AND_COLOR_MODES.split(',').map((mode) => {
225
+ mode = mode.trim();
226
+ if (colorModeToClass[mode as keyof ColorModeConfig]) {
227
+ classes.push(colorModeToClass[mode as keyof ColorModeConfig]);
228
+ } else if (scaleModeToClass[mode as keyof ScaleModeConfig]) {
229
+ classes.push(scaleModeToClass[mode as keyof ScaleModeConfig]);
230
+ }
231
+ });
232
+ } else {
233
+ for (const colorMode in config.colorMode) {
234
+ classes.push(colorModeToClass[colorMode as keyof ColorModeConfig]);
235
+ }
236
+ for (const scaleMode in config.scaleMode) {
237
+ classes.push(scaleModeToClass[scaleMode as keyof ScaleModeConfig]);
238
+ }
239
+ }
240
+
241
+ return classes;
242
+ };
243
+
244
+ type PurgeOptions = {
245
+ config?: string;
246
+ };
247
+
248
+ async function purge({
249
+ config: configPath = Bun.env.UDS_OUT_FILE ?? './uds.config.ts',
250
+ }: PurgeOptions) {
181
251
  const workspaceDir = Bun.env.PWD;
182
252
  const srcDir = path.join(workspaceDir, '/tsconfig.json');
183
253
  const project = new Project({
184
254
  tsConfigFilePath: srcDir,
185
255
  });
186
256
 
257
+ // we need to load the UDS config
258
+ const configAbsolutePath = path.resolve(workspaceDir, configPath);
259
+ const { config } = await import(configAbsolutePath);
260
+
187
261
  spinStart('Getting used UDS components...');
188
- /// 1. Get all files from the current dir
262
+
263
+ // 1. Get all files from the current dir
264
+ print('Loading the project...');
189
265
  const files = await getFiles();
266
+
190
267
  // 2. For each file get the imports;
268
+ print('Going through the imports...');
191
269
  const udsImports = parseFiles(project, files);
192
- // 3. Now that we have the importer components
270
+
271
+ // 3. Now that we have the imported components
272
+ print('Finding all the components imported from UDS...');
193
273
  const udsComponents = getComponentsToConvertToTW(udsImports);
274
+
194
275
  // 4. Generate the CSS we need
276
+ print('🧑‍🍳 Cooking...');
195
277
  const safeList = getTailwindSafelist(project, udsComponents);
278
+ const themesAndScalesClasses = getClassesForEnabledThemesAndScales(config);
279
+
196
280
  // 5. Write the allowlist to a file
197
- await saveToFile(safeList);
281
+ await saveToFile(safeList.concat(themesAndScalesClasses));
282
+
283
+ spinStop('Generated your safelist!');
198
284
  }
199
285
 
200
- export { purge };
286
+ export { purge, type PurgeOptions };
@@ -0,0 +1,38 @@
1
+ import * as react from 'react';
2
+ import { i as UniversalPressableProps, j as UniversalIconButtonProps, k as UniversalImageProps } from './types-COiuE8XK.cjs';
3
+ import { View, PressableProps as PressableProps$1, StyleProp, ViewStyle } from 'react-native';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { ImageProps as ImageProps$1 } from 'expo-image';
6
+
7
+ type NativePressableProps = Omit<PressableProps$1, 'children' | 'style' | 'onPress'> & {
8
+ style?: StyleProp<ViewStyle>;
9
+ };
10
+ interface PressableProps extends UniversalPressableProps, NativePressableProps {
11
+ }
12
+ declare const Pressable: react.ForwardRefExoticComponent<PressableProps & react.RefAttributes<View>>;
13
+
14
+ interface IconButtonProps extends PressableProps, UniversalIconButtonProps {
15
+ }
16
+ /**
17
+ * An icon button element that can be used to trigger an action.
18
+ * @example
19
+ ```tsx
20
+ import { IconButton } from "@yahoo/uds";
21
+
22
+ export function IconButtonDemo() {
23
+ return (
24
+ <IconButton variant="accent-outline" color="primary" name="close" onPress={console.log} />
25
+ )
26
+ }
27
+ ```
28
+ */
29
+ declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<View>>;
30
+
31
+ interface ImageProps extends Omit<ImageProps$1, 'alt' | 'source'>, UniversalImageProps {
32
+ }
33
+ /**
34
+ * An image element
35
+ */
36
+ declare function Image({ width: imageWidth, height: imageHeight, src, alt, contentFit, backgroundColor, borderRadius, borderTopStartRadius, borderTopEndRadius, borderBottomStartRadius, borderBottomEndRadius, borderColor, borderColorOnActive, borderColorOnFocus, borderColorOnChecked, borderColorOnHover, borderStartColor, borderEndColor, borderTopColor, borderBottomColor, borderWidth, borderVerticalWidth, borderHorizontalWidth, borderStartWidth, borderEndWidth, borderTopWidth, borderBottomWidth, alignContent, alignItems, alignSelf, flex, flexDirection, flexGrow, flexShrink, flexWrap, justifyContent, flexBasis, display, overflow, overflowX, overflowY, position, spacing, spacingHorizontal, spacingVertical, spacingBottom, spacingEnd, spacingStart, spacingTop, offset, offsetVertical, offsetHorizontal, offsetBottom, offsetEnd, offsetStart, offsetTop, columnGap, rowGap, minHeight, maxHeight, minWidth, maxWidth, ...props }: ImageProps): react_jsx_runtime.JSX.Element;
37
+
38
+ export { type ImageProps as I, type PressableProps as P, IconButton as a, type IconButtonProps as b, Image as c, Pressable as d };
@@ -0,0 +1,38 @@
1
+ import * as react from 'react';
2
+ import { i as UniversalPressableProps, j as UniversalIconButtonProps, k as UniversalImageProps } from './types-COiuE8XK.js';
3
+ import { View, PressableProps as PressableProps$1, StyleProp, ViewStyle } from 'react-native';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { ImageProps as ImageProps$1 } from 'expo-image';
6
+
7
+ type NativePressableProps = Omit<PressableProps$1, 'children' | 'style' | 'onPress'> & {
8
+ style?: StyleProp<ViewStyle>;
9
+ };
10
+ interface PressableProps extends UniversalPressableProps, NativePressableProps {
11
+ }
12
+ declare const Pressable: react.ForwardRefExoticComponent<PressableProps & react.RefAttributes<View>>;
13
+
14
+ interface IconButtonProps extends PressableProps, UniversalIconButtonProps {
15
+ }
16
+ /**
17
+ * An icon button element that can be used to trigger an action.
18
+ * @example
19
+ ```tsx
20
+ import { IconButton } from "@yahoo/uds";
21
+
22
+ export function IconButtonDemo() {
23
+ return (
24
+ <IconButton variant="accent-outline" color="primary" name="close" onPress={console.log} />
25
+ )
26
+ }
27
+ ```
28
+ */
29
+ declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<View>>;
30
+
31
+ interface ImageProps extends Omit<ImageProps$1, 'alt' | 'source'>, UniversalImageProps {
32
+ }
33
+ /**
34
+ * An image element
35
+ */
36
+ declare function Image({ width: imageWidth, height: imageHeight, src, alt, contentFit, backgroundColor, borderRadius, borderTopStartRadius, borderTopEndRadius, borderBottomStartRadius, borderBottomEndRadius, borderColor, borderColorOnActive, borderColorOnFocus, borderColorOnChecked, borderColorOnHover, borderStartColor, borderEndColor, borderTopColor, borderBottomColor, borderWidth, borderVerticalWidth, borderHorizontalWidth, borderStartWidth, borderEndWidth, borderTopWidth, borderBottomWidth, alignContent, alignItems, alignSelf, flex, flexDirection, flexGrow, flexShrink, flexWrap, justifyContent, flexBasis, display, overflow, overflowX, overflowY, position, spacing, spacingHorizontal, spacingVertical, spacingBottom, spacingEnd, spacingStart, spacingTop, offset, offsetVertical, offsetHorizontal, offsetBottom, offsetEnd, offsetStart, offsetTop, columnGap, rowGap, minHeight, maxHeight, minWidth, maxWidth, ...props }: ImageProps): react_jsx_runtime.JSX.Element;
37
+
38
+ export { type ImageProps as I, type PressableProps as P, IconButton as a, type IconButtonProps as b, Image as c, Pressable as d };