@yahoo/uds 0.3.0 → 0.4.1

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.
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 };