@yahoo/uds 0.4.6 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. package/cli/README.md +15 -2
  2. package/cli/preload.ts +12 -8
  3. package/cli/utils/purgeCSS.test.ts +55 -18
  4. package/cli/utils/purgeCSS.ts +140 -20
  5. package/dist/{Image.native-CfDCpWe_.d.cts → Image.native-Dy2tsvOP.d.ts} +13 -12
  6. package/dist/{Image.native-nwk5tr_f.d.ts → Image.native-DyqCXXic.d.cts} +13 -12
  7. package/dist/{VStack-D-py89Ge.d.cts → VStack-BjW120vC.d.cts} +25 -2
  8. package/dist/{VStack-Bj6PfbK5.d.ts → VStack-CPOOI31y.d.ts} +25 -2
  9. package/dist/experimental/index.cjs +2 -1
  10. package/dist/experimental/index.d.cts +30 -32
  11. package/dist/experimental/index.d.ts +30 -32
  12. package/dist/experimental/index.js +2 -1
  13. package/dist/experimental/index.native.cjs +1 -1
  14. package/dist/experimental/index.native.d.cts +13 -16
  15. package/dist/experimental/index.native.d.ts +13 -16
  16. package/dist/experimental/index.native.js +1 -1
  17. package/dist/fixtures.cjs +1 -664
  18. package/dist/fixtures.d.ts +1 -2
  19. package/dist/fixtures.js +1 -663
  20. package/dist/index.cjs +2 -1
  21. package/dist/index.d.cts +14 -30
  22. package/dist/index.d.ts +14 -30
  23. package/dist/index.js +3 -1
  24. package/dist/{index.native-BLJdXZHY.d.ts → index.native-D-eItswB.d.ts} +1 -1
  25. package/dist/{index.native-A2gCijBH.d.cts → index.native-VZWytAxw.d.cts} +1 -1
  26. package/dist/index.native.cjs +1 -1
  27. package/dist/index.native.d.cts +1122 -10
  28. package/dist/index.native.d.ts +1122 -10
  29. package/dist/index.native.js +1 -1
  30. package/dist/metafile-cjs.json +1 -0
  31. package/dist/metafile-esm.json +1 -0
  32. package/dist/tailwind/plugin.cjs +1 -1
  33. package/dist/tailwind/plugin.d.cts +1 -1
  34. package/dist/tailwind/plugin.d.ts +1 -1
  35. package/dist/tailwind/plugin.js +3 -1
  36. package/dist/tailwind/purger.cjs +3 -1
  37. package/dist/tailwind/purger.d.cts +3 -6
  38. package/dist/tailwind/purger.d.ts +3 -6
  39. package/dist/tailwind/purger.js +3 -1
  40. package/dist/tailwind/tsMorph.cjs +1 -1
  41. package/dist/tailwind/tsMorph.d.cts +4 -1
  42. package/dist/tailwind/tsMorph.d.ts +4 -1
  43. package/dist/tailwind/tsMorph.js +3 -1
  44. package/dist/tokens/index.cjs +2 -1
  45. package/dist/tokens/index.d.cts +1097 -3
  46. package/dist/tokens/index.d.ts +1097 -3
  47. package/dist/tokens/index.js +2 -1
  48. package/dist/tokens/index.native.d.cts +2 -2
  49. package/dist/tokens/index.native.d.ts +2 -2
  50. package/dist/tokens/parseTokens.cjs +2 -1
  51. package/dist/tokens/parseTokens.d.cts +1 -1
  52. package/dist/tokens/parseTokens.d.ts +1 -1
  53. package/dist/tokens/parseTokens.js +2 -1
  54. package/dist/{types-Diou6f1Q.d.cts → types-Cy3fKMaw.d.cts} +21 -20
  55. package/dist/{types-Diou6f1Q.d.ts → types-Cy3fKMaw.d.ts} +21 -20
  56. package/dist/{types-Dk8fLx7L.d.cts → types-at8CTkly.d.cts} +21 -20
  57. package/dist/{types-Dk8fLx7L.d.ts → types-at8CTkly.d.ts} +21 -20
  58. package/package.json +20 -19
package/cli/README.md CHANGED
@@ -46,7 +46,7 @@ uds sync --id [id] --outFile [path]
46
46
  uds sync --id [id]
47
47
  ```
48
48
 
49
- #### Enviornment variables
49
+ #### Environment variables
50
50
 
51
51
  Alternatively, you can use environment variables instead of flags.
52
52
 
@@ -86,7 +86,20 @@ For more information about safelisting classes in Tailwind, visit the [official
86
86
  uds purge
87
87
  ```
88
88
 
89
- #### Enviornment variables
89
+ #### Flags
90
+
91
+ | Flag | Description | Default | Required |
92
+ | -------- | --------------------------- | ------------------ | -------- |
93
+ | `output` | Output path of the safelist | ./dist/safelist.ts | |
94
+ | `config` | UDS config | ./uds.config.ts | |
95
+
96
+ **Example:**
97
+
98
+ ```shell
99
+ uds purge --output output/dir
100
+ ```
101
+
102
+ #### Environment variables
90
103
 
91
104
  | Variable | Description | Default | Required |
92
105
  | ------------------------------- | ------------------------------------------- | ------- | -------- |
package/cli/preload.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { jest, mock } from 'bun:test';
1
+ import { mock, spyOn } from 'bun:test';
2
2
 
3
- const mockFastGlob = jest.fn().mockResolvedValue(['/pages/PageA.tsx', '/pages/PageB.tsx']);
4
-
5
- mock.module('fast-glob', () => ({ __esModule: true, default: mockFastGlob }));
3
+ spyOn(global.Bun.Glob.prototype, 'scan').mockImplementation(() => {
4
+ return ['/pages/PageA.tsx', '/pages/PageB.tsx'] as unknown as AsyncIterableIterator<string>;
5
+ });
6
6
 
7
7
  mock.module('@yahoo/uds/tailwind/purger', () => ({
8
8
  componentsDependencies: {
@@ -11,15 +11,19 @@ mock.module('@yahoo/uds/tailwind/purger', () => ({
11
11
  HStack: ['Box'],
12
12
  },
13
13
  componentToVariants: {
14
- Button: ['color'],
15
- HStack: ['alignItems', 'justifyContent'],
16
- Icon: ['color'],
14
+ Button: [['color', ['accent']]],
15
+ HStack: [
16
+ ['alignItems', ['flex-start']],
17
+ ['justifyContent', ['flex-start']],
18
+ ],
19
+ Icon: [['color', ['accent']]],
17
20
  Text: ['fontSize', 'fontFamily'],
18
21
  Pressable: ['display'],
19
22
  },
20
23
  variantsList: ['color', 'alignItems', 'justifyContent', 'display', 'fontSize', 'fontFamily'],
21
24
  variantToTailwindClass: {
22
- color: 'text-accent text-alert text-black text-brand text-positive text-warning text-white',
25
+ color:
26
+ 'container text-accent text-alert text-black text-brand text-positive text-warning text-white',
23
27
  alignItems: 'items-start items-end items-center items-stretch items-baseline',
24
28
  justifyContent:
25
29
  'justify-start justify-end justify-center justify-between justify-around justify-evenly',
@@ -9,10 +9,11 @@ import {
9
9
  getUsedProps,
10
10
  isUDSComponent,
11
11
  parseFiles,
12
+ scanGetStylesReferences,
12
13
  } from './purgeCSS';
13
14
 
14
15
  const PAGE_A_CODE = `
15
- import { HStack, Button } from '@yahoo/uds';
16
+ import { HStack, Button, getStyles } from '@yahoo/uds';
16
17
 
17
18
  const functionWithProp = () => {
18
19
  const vars = {
@@ -27,10 +28,20 @@ const functionWithProp = () => {
27
28
 
28
29
  const AnotherComponent = () => {
29
30
  const propsList = functionWithProp();
30
- return <HStack test="test" {...propsList}>meow</HStack>
31
+
32
+ const classNames = getStyles({
33
+ borderStartColor: 'primary'
34
+ });
35
+
36
+ return <HStack testProp="testValue" classNames={classNames} {...propsList}>meow</HStack>
31
37
  }
32
38
 
33
39
  const PageA = () => {
40
+ const justifyContent = 'justify-start';
41
+ const classNames = getStyles({
42
+ justifyContent
43
+ });
44
+
34
45
  return (
35
46
  <div>
36
47
  <HStack />
@@ -56,7 +67,7 @@ const PageB = () => {
56
67
  `;
57
68
 
58
69
  const FILES = ['/pages/PageA.tsx', '/pages/PageB.tsx'];
59
- const IMPORTED_UDS_COMPONENTS = ['HStack', 'Button', 'Spinner'];
70
+ const IMPORTED_UDS_COMPONENTS = ['HStack', 'Button', 'getStyles', 'Spinner'];
60
71
 
61
72
  describe('purgeCSS', () => {
62
73
  const project = new Project();
@@ -85,24 +96,23 @@ describe('purgeCSS', () => {
85
96
  });
86
97
 
87
98
  describe('getTailwindSafelist', () => {
88
- it('returns the tailwind classes corresponding to the props on a component', () => {
99
+ it('returns the tailwind classes required for all the components', () => {
100
+ project.createSourceFile(FILES[0], PAGE_A_CODE, {
101
+ overwrite: true,
102
+ });
103
+ project.createSourceFile(FILES[1], PAGE_B_CODE, {
104
+ overwrite: true,
105
+ });
106
+
89
107
  const res = getTailwindSafelist(project, IMPORTED_UDS_COMPONENTS);
90
108
 
91
109
  expect(res).toEqual([
92
110
  'container',
93
111
  'fill',
94
- '',
95
112
  'items-start',
96
- 'items-end',
97
113
  'items-center',
98
- 'items-stretch',
99
- 'items-baseline',
100
114
  'justify-start',
101
- 'justify-end',
102
115
  'justify-center',
103
- 'justify-between',
104
- 'justify-around',
105
- 'justify-evenly',
106
116
  'text-accent',
107
117
  'text-alert',
108
118
  'text-black',
@@ -110,6 +120,13 @@ describe('purgeCSS', () => {
110
120
  'text-positive',
111
121
  'text-warning',
112
122
  'text-white',
123
+ 'text-transparent',
124
+ 'text-muted',
125
+ 'text-on-color',
126
+ 'text-primary',
127
+ 'text-secondary',
128
+ 'text-tertiary',
129
+ 'border-s-primary',
113
130
  ]);
114
131
  });
115
132
  });
@@ -148,12 +165,13 @@ describe('purgeCSS', () => {
148
165
  const usedProps = getUsedProps(project, 'HStack');
149
166
 
150
167
  expect(usedProps).toEqual([
151
- 'test',
152
- 'color',
153
- 'isActive',
154
- 'flexGrow',
155
- 'alignItems',
156
- 'justifyContent',
168
+ ['testProp', ['testValue']],
169
+ ['classNames', []],
170
+ ['color', []],
171
+ ['isActive', []],
172
+ ['flexGrow', ['1']],
173
+ ['alignItems', ['center']],
174
+ ['justifyContent', ['center']],
157
175
  ]);
158
176
  });
159
177
  });
@@ -169,4 +187,23 @@ describe('purgeCSS', () => {
169
187
  ]);
170
188
  });
171
189
  });
190
+
191
+ describe('scanGetStylesReferences', () => {
192
+ it('should scan the project for getStyles references and return the used variants', () => {
193
+ project.createSourceFile(FILES[0], PAGE_A_CODE, {
194
+ overwrite: true,
195
+ });
196
+ project.createSourceFile(FILES[1], PAGE_B_CODE, {
197
+ overwrite: true,
198
+ });
199
+
200
+ const res = scanGetStylesReferences(project);
201
+
202
+ const expectedResult = new Map();
203
+ expectedResult.set('borderStartColor', new Set(['primary']));
204
+ expectedResult.set('justifyContent', new Set([]));
205
+
206
+ expect(res).toEqual(expectedResult);
207
+ });
208
+ });
172
209
  });
@@ -5,7 +5,6 @@ import {
5
5
  componentToTwClasses,
6
6
  componentToVariants,
7
7
  variantsList,
8
- variantToTailwindClass,
9
8
  } from '@yahoo/uds/tailwind/purger';
10
9
  import { findReferencesAsJsxElements, getUsedPropsInReference } from '@yahoo/uds/tailwind/tsMorph';
11
10
  import {
@@ -17,6 +16,7 @@ import {
17
16
  ScaleModeConfig,
18
17
  SMALL_SCALE_MODE_CLASSNAME,
19
18
  UniversalTokensConfig,
19
+ variants,
20
20
  XLARGE_SCALE_MODE_CLASSNAME,
21
21
  XSMALL_SCALE_MODE_CLASSNAME,
22
22
  XXLARGE_SCALE_MODE_CLASSNAME,
@@ -24,8 +24,18 @@ import {
24
24
  } from '@yahoo/uds/tokens';
25
25
  import { print, spinStart, spinStop } from 'bluebun';
26
26
  import { BunFile } from 'bun';
27
- import FastGlob from 'fast-glob';
28
- import { JsxOpeningElement, JsxSelfClosingElement, Project, ts } from 'ts-morph';
27
+ import { uniq } from 'lodash-es';
28
+ import {
29
+ CallExpression,
30
+ JsxOpeningElement,
31
+ JsxSelfClosingElement,
32
+ Node,
33
+ Project,
34
+ SyntaxKind,
35
+ ts,
36
+ } from 'ts-morph';
37
+
38
+ import packageJson from '../../package.json';
29
39
 
30
40
  const scaleModeToClass: { [key in keyof ScaleModeConfig]: string } = {
31
41
  large: LARGE_SCALE_MODE_CLASSNAME,
@@ -49,9 +59,8 @@ type Files = string[];
49
59
  export const getFiles = async (): Promise<Files> => {
50
60
  const workspaceDir = Bun.env.PWD;
51
61
  const srcDir = path.join(workspaceDir, '/src/');
52
- const files = await FastGlob(`${srcDir}/**/*.{jsx,tsx}`);
53
-
54
- return files;
62
+ const glob = new Bun.Glob('**/*.{jsx,tsx}');
63
+ return Array.fromAsync(glob.scan({ cwd: srcDir, absolute: true }));
55
64
  };
56
65
 
57
66
  /**
@@ -125,23 +134,34 @@ export const parseFiles = (project: Project, files: Files): ImportsList => {
125
134
  export const getTailwindSafelist = (project: Project, componentList: string[]): SafeList => {
126
135
  const safeList: SafeList = [];
127
136
  const validVariants = new Set<string>(variantsList);
128
- const usedProps = new Set<string>();
137
+ // we track the prop name and which values have been used
138
+ const usedProps = new Map<string, Set<string>>();
129
139
  componentList.forEach((component: string) => {
130
140
  if (isUDSComponent(component)) {
131
141
  // get the TW classes relevant for each prop
132
142
  // these classes are used internally in UDS,
133
143
  // they either have been initialized or used by other UDS components
134
- componentToVariants[component].forEach((prop: string) => {
135
- if (validVariants.has(prop) && !usedProps.has(prop)) {
136
- usedProps.add(prop);
144
+ componentToVariants[component].forEach(([propName, usedValues]) => {
145
+ if (validVariants.has(propName)) {
146
+ const options: Set<string> = usedProps.get(propName) ?? new Set();
147
+ usedValues.forEach((val) => options.add(val));
148
+ usedProps.set(propName, options);
137
149
  }
138
150
  });
139
151
 
140
152
  // scan the project for used props and
141
153
  // get the corresponding css for those used props
142
- getUsedProps(project, component).forEach((prop: string) => {
143
- if (validVariants.has(prop) && !usedProps.has(prop)) {
144
- usedProps.add(prop);
154
+ getUsedProps(project, component).forEach(([propName, usedValues]) => {
155
+ if (validVariants.has(propName)) {
156
+ // This means that an expression has been used (Ex: `<Button size={getSize()} />`)
157
+ // so we need to add all possible options for that prop
158
+ if (usedValues.length === 0) {
159
+ usedValues = Object.keys(variants[propName as keyof typeof variants]);
160
+ }
161
+
162
+ const options: Set<string> = usedProps.get(propName) ?? new Set();
163
+ usedValues.forEach((val) => options.add(val));
164
+ usedProps.set(propName, options);
145
165
  }
146
166
  });
147
167
 
@@ -150,11 +170,20 @@ export const getTailwindSafelist = (project: Project, componentList: string[]):
150
170
  }
151
171
  });
152
172
 
153
- for (const prop of usedProps) {
154
- safeList.push(...variantToTailwindClass[prop].replaceAll('\\', '').split(' '));
173
+ for (const [propName, usedValues] of usedProps) {
174
+ usedValues.forEach((option) => {
175
+ safeList.push((variants[propName as never][option] as string)?.replaceAll('\\', ''));
176
+ });
155
177
  }
156
178
 
157
- return safeList;
179
+ for (const [variant, variantOptions] of scanGetStylesReferences(project)) {
180
+ variantOptions.forEach((option) => {
181
+ safeList.push((variants[variant as never][option] as string)?.replaceAll('\\', ''));
182
+ });
183
+ }
184
+
185
+ // Return a deduped list and strip out any empty strings
186
+ return uniq(safeList.filter(Boolean));
158
187
  };
159
188
 
160
189
  /**
@@ -163,12 +192,13 @@ export const getTailwindSafelist = (project: Project, componentList: string[]):
163
192
  * @example
164
193
  * const usedProps = getUsedProps(project, 'HStack');
165
194
  */
166
- export const getUsedProps = (project: Project, component: string) => {
195
+ export const getUsedProps = (project: Project, component: string): Array<[string, string[]]> => {
167
196
  const references: (JsxOpeningElement | JsxSelfClosingElement)[] = [];
168
- references.push(...findNamedImportReferences(project, '@yahoo/uds', component));
169
- references.push(...findNamedImportReferences(project, '@yahoo/uds/experimental', component));
197
+ references.push(...findNamedImportReferences(project, packageJson.name, component));
198
+ references.push(
199
+ ...findNamedImportReferences(project, `${packageJson.name}/experimental`, component),
200
+ );
170
201
 
171
- // for each reference find the used/references props
172
202
  const usedProps = references.map((reference) => getUsedPropsInReference(reference)).flat();
173
203
 
174
204
  return usedProps;
@@ -234,6 +264,96 @@ export const getClassesForEnabledThemesAndScales = (): string[] => {
234
264
  return classes;
235
265
  };
236
266
 
267
+ /**
268
+ * Scan the source code for all `getStyles` references
269
+ *
270
+ * Note: This currently only works if we are passing a literal object to getStyles.
271
+ *
272
+ * Explanation: They we are able to enfer what css to include is by looking at the properties of the object passed.
273
+ * If something other than an object is passed, we can fallback on the Type, but that would require handling
274
+ * a lot of edge cases (function return type, spread operator, ternary, ...) and each one of these cases will
275
+ * most likely have a sub case. Falling back to the Type will complicate the code a lot is error prone as there
276
+ * is only so much info we can get out of the types as the Users are free to use `any` on their project which will
277
+ * provide no value for us. Hence why having a literal object passed is the best and probably the only sane way
278
+ * to go about this.
279
+ */
280
+ export const scanGetStylesReferences = (project: Project): Map<string, Set<string>> => {
281
+ // Find all the references for `getStyles`
282
+ const references: CallExpression[] = [];
283
+ for (const sourceFile of project.getSourceFiles()) {
284
+ for (const importDeclaration of sourceFile.getImportDeclarations()) {
285
+ if (importDeclaration.getModuleSpecifierValue() === packageJson.name) {
286
+ for (const namedImport of importDeclaration.getNamedImports()) {
287
+ if (namedImport.getName() === 'getStyles') {
288
+ const identifier = namedImport.getFirstDescendantByKindOrThrow(
289
+ ts.SyntaxKind.Identifier,
290
+ );
291
+
292
+ for (const reference of identifier.findReferencesAsNodes()) {
293
+ const node = reference.getFirstAncestor((node) => {
294
+ return Node.isCallExpression(node);
295
+ });
296
+
297
+ if (node) {
298
+ references.push(node as CallExpression);
299
+ }
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ const usedProps = new Map<string, Set<string>>();
308
+ for (const reference of references) {
309
+ // TODO: handle the throw, tell users to not use something other than an object when calling `getStyles`
310
+ const objectLiteralExpression = reference.getFirstChildByKindOrThrow(
311
+ SyntaxKind.ObjectLiteralExpression,
312
+ );
313
+ const propertyAssignments = objectLiteralExpression.getDescendantsOfKind(
314
+ SyntaxKind.PropertyAssignment,
315
+ ); // PropertyAssignment is { property: 'test' }
316
+ const shorthandPropertyAssignments = objectLiteralExpression.getDescendantsOfKind(
317
+ SyntaxKind.ShorthandPropertyAssignment,
318
+ ); // ShorthandPropertyAssignment is { property }
319
+ // TODO: handle spread assignment
320
+ propertyAssignments.forEach((propertyAssigment) => {
321
+ const identifier = propertyAssigment.getFirstChildByKind(SyntaxKind.Identifier)?.getText();
322
+ // check if we are assigning a string
323
+ const stringLiteral = propertyAssigment
324
+ .getFirstChildByKind(SyntaxKind.StringLiteral)
325
+ ?.getLiteralText();
326
+ if (identifier && !stringLiteral) {
327
+ // this means an expression has been used
328
+ // so we add all the possibilites
329
+ const isvalidVariant = !!variants[identifier as keyof typeof variants];
330
+ const fallback = isvalidVariant
331
+ ? Object.keys(variants[identifier as keyof typeof variants])
332
+ : [];
333
+ usedProps.set(identifier, new Set(fallback));
334
+ }
335
+ if (identifier && stringLiteral) {
336
+ let options: Set<string>;
337
+ if (usedProps.has(identifier)) {
338
+ options = usedProps.get(identifier)!;
339
+ } else {
340
+ options = new Set();
341
+ }
342
+ options.add(stringLiteral);
343
+ usedProps.set(identifier, options);
344
+ }
345
+ });
346
+ shorthandPropertyAssignments.forEach((propertyAssigment) => {
347
+ const identifier = propertyAssigment.getFirstChildByKind(SyntaxKind.Identifier)?.getText();
348
+ if (identifier) {
349
+ usedProps.set(identifier, new Set());
350
+ }
351
+ });
352
+ }
353
+
354
+ return usedProps;
355
+ };
356
+
237
357
  type PurgeOptions = {
238
358
  config?: string;
239
359
  output?: string;
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { b as UniversalPressableProps, c as UniversalIconButtonProps, d as UniversalImageProps } from './types-Dk8fLx7L.cjs';
2
+ import { b as UniversalPressableProps, c as UniversalIconButtonProps, d as UniversalImageProps } from './types-at8CTkly.js';
3
3
  import { View, PressableProps as PressableProps$1, StyleProp, ViewStyle } from 'react-native';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ImageProps as ImageProps$1 } from 'expo-image';
@@ -14,17 +14,18 @@ declare const Pressable: react.ForwardRefExoticComponent<PressableProps & react.
14
14
  interface IconButtonProps extends PressableProps, UniversalIconButtonProps {
15
15
  }
16
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
- ```
17
+ * An icon button is essentially an interactive icon. They should be used to
18
+ * display an icon which, when clicked, allows the user to trigger an action.
19
+ * Icon buttons provide additional features such hover states, focus states, and
20
+ * pressable functionality.
21
+ *
22
+ * **Basic usage**
23
+ * ```tsx
24
+ * import { IconButton } from "@yahoo/uds";
25
+ * import { AddFolder } from "@yahoo/uds-icons";
26
+ *
27
+ * <IconButton name={AddFolder} color="primary" variant="accent" iconVariant="outline" />
28
+ * ```
28
29
  */
29
30
  declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<View>>;
30
31
 
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { b as UniversalPressableProps, c as UniversalIconButtonProps, d as UniversalImageProps } from './types-Dk8fLx7L.js';
2
+ import { b as UniversalPressableProps, c as UniversalIconButtonProps, d as UniversalImageProps } from './types-at8CTkly.cjs';
3
3
  import { View, PressableProps as PressableProps$1, StyleProp, ViewStyle } from 'react-native';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ImageProps as ImageProps$1 } from 'expo-image';
@@ -14,17 +14,18 @@ declare const Pressable: react.ForwardRefExoticComponent<PressableProps & react.
14
14
  interface IconButtonProps extends PressableProps, UniversalIconButtonProps {
15
15
  }
16
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
- ```
17
+ * An icon button is essentially an interactive icon. They should be used to
18
+ * display an icon which, when clicked, allows the user to trigger an action.
19
+ * Icon buttons provide additional features such hover states, focus states, and
20
+ * pressable functionality.
21
+ *
22
+ * **Basic usage**
23
+ * ```tsx
24
+ * import { IconButton } from "@yahoo/uds";
25
+ * import { AddFolder } from "@yahoo/uds-icons";
26
+ *
27
+ * <IconButton name={AddFolder} color="primary" variant="accent" iconVariant="outline" />
28
+ * ```
28
29
  */
29
30
  declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<View>>;
30
31
 
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { Ref } from 'react';
3
- import { g as UniversalBoxProps, h as UniversalPressableProps, i as UniversalTextProps, j as UniversalStackProps } from './types-Diou6f1Q.cjs';
3
+ import { aH as UniversalBoxProps, aK as UniversalIconProps, aL as UniversalPressableProps, aN as UniversalTextProps, g as UniversalStackProps } from './types-Cy3fKMaw.cjs';
4
4
 
5
5
  type DivProps = React.HTMLAttributes<HTMLDivElement>;
6
6
  interface BoxProps extends UniversalBoxProps, DivProps {
@@ -23,6 +23,29 @@ interface BoxProps extends UniversalBoxProps, DivProps {
23
23
  */
24
24
  declare const Box: react.ForwardRefExoticComponent<BoxProps & react.RefAttributes<HTMLDivElement>>;
25
25
 
26
+ type SVGElementProps = Omit<React.HTMLAttributes<SVGSVGElement>, 'color'>;
27
+ interface IconProps extends UniversalIconProps, SVGElementProps {
28
+ }
29
+ /**
30
+ * Icons are small symbols for actions or other items. They are available in
31
+ * three different sizes: `sm`, `md`, and `lg`. Each size also supports an
32
+ * outline and fill variant. Icons can be colored using the `color` prop.
33
+ *
34
+ * The component is available in the `@yahoo/uds` package but is meant to be used
35
+ * with the assets in `@yahoo/uds-icons`. You will need both packages to use icons.
36
+ * A separate package provides modularity from the core library, better
37
+ * versioning strategies, and tree shakeability.
38
+ *
39
+ * **Basic usage**
40
+ * ```tsx
41
+ * import { Icon } from '@yahoo/uds';
42
+ * import { AddFolder } from '@yahoo/uds-icons';
43
+ *
44
+ * <Icon name={AddFolder} variant="fill" size="sm" />
45
+ * ```
46
+ */
47
+ declare const Icon: react.ForwardRefExoticComponent<IconProps & react.RefAttributes<SVGSVGElement>>;
48
+
26
49
  type HtmlButtonProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'color' | 'name'>;
27
50
  interface PressableProps extends UniversalPressableProps, HtmlButtonProps {
28
51
  }
@@ -100,4 +123,4 @@ type VStackProps = UniversalStackProps & DivProps;
100
123
  **/
101
124
  declare const VStack: react.ForwardRefExoticComponent<UniversalStackProps & DivProps & react.RefAttributes<HTMLDivElement>>;
102
125
 
103
- export { Box as B, type DivProps as D, Pressable as P, Text as T, VStack as V, type BoxProps as a, type PressableProps as b, type TextProps as c, type VStackProps as d };
126
+ export { Box as B, type DivProps as D, Icon as I, Pressable as P, Text as T, VStack as V, type BoxProps as a, type IconProps as b, type PressableProps as c, type TextProps as d, type VStackProps as e };
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { Ref } from 'react';
3
- import { g as UniversalBoxProps, h as UniversalPressableProps, i as UniversalTextProps, j as UniversalStackProps } from './types-Diou6f1Q.js';
3
+ import { aH as UniversalBoxProps, aK as UniversalIconProps, aL as UniversalPressableProps, aN as UniversalTextProps, g as UniversalStackProps } from './types-Cy3fKMaw.js';
4
4
 
5
5
  type DivProps = React.HTMLAttributes<HTMLDivElement>;
6
6
  interface BoxProps extends UniversalBoxProps, DivProps {
@@ -23,6 +23,29 @@ interface BoxProps extends UniversalBoxProps, DivProps {
23
23
  */
24
24
  declare const Box: react.ForwardRefExoticComponent<BoxProps & react.RefAttributes<HTMLDivElement>>;
25
25
 
26
+ type SVGElementProps = Omit<React.HTMLAttributes<SVGSVGElement>, 'color'>;
27
+ interface IconProps extends UniversalIconProps, SVGElementProps {
28
+ }
29
+ /**
30
+ * Icons are small symbols for actions or other items. They are available in
31
+ * three different sizes: `sm`, `md`, and `lg`. Each size also supports an
32
+ * outline and fill variant. Icons can be colored using the `color` prop.
33
+ *
34
+ * The component is available in the `@yahoo/uds` package but is meant to be used
35
+ * with the assets in `@yahoo/uds-icons`. You will need both packages to use icons.
36
+ * A separate package provides modularity from the core library, better
37
+ * versioning strategies, and tree shakeability.
38
+ *
39
+ * **Basic usage**
40
+ * ```tsx
41
+ * import { Icon } from '@yahoo/uds';
42
+ * import { AddFolder } from '@yahoo/uds-icons';
43
+ *
44
+ * <Icon name={AddFolder} variant="fill" size="sm" />
45
+ * ```
46
+ */
47
+ declare const Icon: react.ForwardRefExoticComponent<IconProps & react.RefAttributes<SVGSVGElement>>;
48
+
26
49
  type HtmlButtonProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'color' | 'name'>;
27
50
  interface PressableProps extends UniversalPressableProps, HtmlButtonProps {
28
51
  }
@@ -100,4 +123,4 @@ type VStackProps = UniversalStackProps & DivProps;
100
123
  **/
101
124
  declare const VStack: react.ForwardRefExoticComponent<UniversalStackProps & DivProps & react.RefAttributes<HTMLDivElement>>;
102
125
 
103
- export { Box as B, type DivProps as D, Pressable as P, Text as T, VStack as V, type BoxProps as a, type PressableProps as b, type TextProps as c, type VStackProps as d };
126
+ export { Box as B, type DivProps as D, Icon as I, Pressable as P, Text as T, VStack as V, type BoxProps as a, type IconProps as b, type PressableProps as c, type TextProps as d, type VStackProps as e };