@adobe-commerce/elsie 1.4.1-alpha008 → 1.5.0-alpha1

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.
@@ -77,20 +77,24 @@ module.exports = async function generateResourceBuilder(yargs) {
77
77
  alias: 's',
78
78
  describe: 'Path to the source code containing GraphQL operations',
79
79
  type: 'array',
80
- string: true,
81
80
  demandOption: true,
82
81
  })
82
+ .option('excluded', {
83
+ alias: 'x',
84
+ describe: 'Paths to exclude from validation',
85
+ type: 'array',
86
+ demandOption: false,
87
+ })
83
88
  .option('endpoints', {
84
89
  alias: 'e',
85
90
  describe: 'Path to GraphQL endpoints',
86
91
  type: 'array',
87
- string: true,
88
92
  demandOption: true,
89
93
  });
90
94
  },
91
95
  async (argv) => {
92
- const { source, endpoints } = argv;
93
- await validate(source, endpoints);
96
+ const { source, excluded, endpoints } = argv;
97
+ await validate(source, endpoints, excluded);
94
98
  },
95
99
  )
96
100
  .demandCommand(1, 1, 'choose a command: types, mocks or validate');
@@ -5,17 +5,20 @@ const parser = require('@babel/parser');
5
5
  const traverse = require('@babel/traverse');
6
6
  const { getIntrospectionQuery, buildClientSchema, parse, validate } = require('graphql');
7
7
 
8
- async function walk(dir, collected = []) {
8
+ async function walk(dir, excludedPaths = [], collected = []) {
9
+ if (excludedPaths.includes(dir)) return collected;
10
+
9
11
  const dirents = await fsPromises.readdir(dir, { withFileTypes: true });
10
12
 
11
13
  for (const d of dirents) {
12
14
  const full = path.resolve(dir, d.name);
13
15
 
14
16
  if (d.isDirectory()) {
15
- // skip node_modules and “hidden” folders such as .git
17
+ if (excludedPaths.includes(full)) continue;
16
18
  if (d.name === 'node_modules' || d.name.startsWith('.')) continue;
17
- await walk(full, collected);
19
+ await walk(full, excludedPaths, collected);
18
20
  } else if (/\.(c?m?js|ts|tsx)$/.test(d.name)) {
21
+ if (excludedPaths.includes(full)) continue;
19
22
  collected.push(full);
20
23
  }
21
24
  }
@@ -97,10 +100,10 @@ async function validateGqlOperations(endpoint, operation) {
97
100
  }
98
101
  }
99
102
 
100
- async function getAllOperations(directories) {
103
+ async function getAllOperations(directories, excludedPaths = []) {
101
104
  let fullContent = '';
102
105
  for (const directory of directories) {
103
- const files = await walk(path.resolve(directory));
106
+ const files = await walk(path.resolve(directory), excludedPaths.map(p => path.resolve(p)));
104
107
  for (const f of files) {
105
108
  const code = await fsPromises.readFile(f, 'utf8');
106
109
 
@@ -120,11 +123,9 @@ async function getAllOperations(directories) {
120
123
  return fullContent;
121
124
  }
122
125
 
123
-
124
-
125
- module.exports = async function main(sources, endpoints) {
126
+ module.exports = async function main(sources, endpoints, excluded) {
126
127
  for (const endpoint of endpoints) {
127
- const operations = await getAllOperations(sources);
128
+ const operations = await getAllOperations(sources, excluded);
128
129
  if (!operations) {
129
130
  console.error('No GraphQL operations found in the specified directories.');
130
131
  process.exitCode = 0;
@@ -132,4 +133,4 @@ module.exports = async function main(sources, endpoints) {
132
133
  }
133
134
  await validateGqlOperations(endpoint, operations);
134
135
  }
135
- }
136
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe-commerce/elsie",
3
- "version": "1.4.1-alpha008",
3
+ "version": "1.5.0-alpha1",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "description": "Domain Package SDK",
6
6
  "engines": {
@@ -26,7 +26,7 @@
26
26
  "cleanup": "rimraf dist"
27
27
  },
28
28
  "devDependencies": {
29
- "@adobe-commerce/event-bus": "1.0.1-beta1",
29
+ "@adobe-commerce/event-bus": "~1.0.1",
30
30
  "@adobe-commerce/fetch-graphql": "~1.1.0",
31
31
  "@adobe-commerce/recaptcha": "~1.0.1",
32
32
  "@adobe-commerce/storefront-design": "~1.0.0",
@@ -0,0 +1,49 @@
1
+ /********************************************************************
2
+ * Copyright 2025 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ /* https://cssguidelin.es/#bem-like-naming */
11
+
12
+ .dropin-input-file__input {
13
+ display: none;
14
+ }
15
+
16
+ .dropin-input-file__label {
17
+ border: 0 none;
18
+ cursor: pointer;
19
+ border-radius: var(--shape-border-radius-3);
20
+ padding: var(--spacing-xsmall) var(--spacing-medium);
21
+ display: flex;
22
+ justify-content: center;
23
+ align-items: center;
24
+ background: var(--color-brand-500);
25
+ color: var(--color-neutral-50);
26
+ font: var(--type-button-2-font);
27
+ letter-spacing: var(--type-button-2-letter-spacing);
28
+ }
29
+
30
+ .dropin-input-file__label:hover {
31
+ background-color: var(--color-button-hover);
32
+ }
33
+
34
+ .dropin-input-file__icon {
35
+ height: 24px;
36
+ margin-right: var(--spacing-xsmall);
37
+ }
38
+
39
+ /* Medium (portrait tablets and large phones, 768px and up) */
40
+ /* @media only screen and (min-width: 768px) { } */
41
+
42
+ /* Large (landscape tablets, 1024px and up) */
43
+ /* @media only screen and (min-width: 1024px) { } */
44
+
45
+ /* XLarge (laptops/desktops, 1366px and up) */
46
+ /* @media only screen and (min-width: 1366px) { } */
47
+
48
+ /* XXlarge (large laptops and desktops, 1920px and up) */
49
+ /* @media only screen and (min-width: 1920px) { } */
@@ -0,0 +1,90 @@
1
+ /********************************************************************
2
+ * Copyright 2025 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ // https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
11
+ import type { Meta, StoryObj } from '@storybook/preact';
12
+ import { InputFile, InputFileProps } from '@adobe-commerce/elsie/components/InputFile';
13
+ import { action } from '@storybook/addon-actions';
14
+ import { IconsList } from '@adobe-commerce/elsie/components/Icon/Icon.stories.helpers';
15
+
16
+ /**
17
+ * Use InputFile to upload files.
18
+ */
19
+ const meta: Meta<InputFileProps> = {
20
+ title: 'Components/InputFile',
21
+ component: InputFile,
22
+ argTypes: {
23
+ label: {
24
+ description: 'Label for the input file.',
25
+ type: 'string',
26
+ },
27
+ accept: {
28
+ description: 'Restrict selectable file types',
29
+ type: 'string',
30
+ },
31
+ multiple: {
32
+ description: 'Allow multiple files selection.',
33
+ type: {
34
+ name: 'boolean',
35
+ required: false
36
+ },
37
+ },
38
+ id: {
39
+ description: 'id',
40
+ type: {
41
+ required: false,
42
+ name: 'string'
43
+ },
44
+ control: 'text',
45
+ },
46
+ onChange: {
47
+ description: 'Handler for when the file selection changes.',
48
+ control: false,
49
+ table: {
50
+ type: {
51
+ summary: 'function'
52
+ },
53
+ },
54
+ },
55
+ icon: {
56
+ description: 'Optional icon.',
57
+ table: {
58
+ type: { summary: 'FunctionComponent' },
59
+ },
60
+ options: Object.keys(IconsList),
61
+ mapping: IconsList,
62
+ control: 'select',
63
+ },
64
+ },
65
+ };
66
+
67
+ export default meta;
68
+
69
+ type Story = StoryObj<InputFileProps>;
70
+
71
+ export const Default: Story = {
72
+ args: {
73
+ label: 'Upload File',
74
+ id: 'single-file-input',
75
+ accept: ".pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt, .csv, .jpg, .jpeg, .png, .gif, .bmp, .tiff, .ico, .webp",
76
+ onChange: action('onChange'),
77
+ icon: 'none' as any,
78
+ },
79
+ };
80
+
81
+ export const MultipleFiles: Story = {
82
+ args: {
83
+ label: 'Upload Multiple Files',
84
+ id: 'multiple-files-input',
85
+ accept: ".pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt, .csv, .jpg, .jpeg, .png, .gif, .bmp, .tiff, .ico, .webp",
86
+ multiple: true,
87
+ onChange: action('onChange'),
88
+ icon: 'none' as any,
89
+ },
90
+ };
@@ -0,0 +1,59 @@
1
+ /********************************************************************
2
+ * Copyright 2025 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ import { FunctionComponent, VNode } from 'preact';
11
+ import { useId } from 'preact/hooks';
12
+ import { HTMLAttributes } from 'preact/compat';
13
+ import { classes } from '@adobe-commerce/elsie/lib';
14
+ import '@adobe-commerce/elsie/components/InputFile/InputFile.css';
15
+
16
+ export interface InputFileProps extends Omit<HTMLAttributes<HTMLInputElement>, 'type' | 'icon'> {
17
+ accept?: string;
18
+ onChange?: (event: Event) => void;
19
+ label?: string;
20
+ multiple?: boolean;
21
+ icon?: VNode<HTMLAttributes<SVGSVGElement>>;
22
+ }
23
+
24
+ export const InputFile: FunctionComponent<InputFileProps> = ({
25
+ accept,
26
+ onChange,
27
+ label = 'Upload Document',
28
+ icon,
29
+ className,
30
+ multiple,
31
+ id: providedId,
32
+ ...props
33
+ }) => {
34
+
35
+ const generatedId = useId();
36
+ const id = providedId || generatedId;
37
+
38
+ const handleChange = (e: Event) => {
39
+ onChange?.(e);
40
+ };
41
+
42
+ return (
43
+ <div className={classes(['dropin-input-file', className])}>
44
+ <label htmlFor={id} className="dropin-input-file__label">
45
+ {icon && <span className="dropin-input-file__icon">{icon}</span>}
46
+ {label}
47
+ </label>
48
+ <input
49
+ id={id}
50
+ type="file"
51
+ accept={accept}
52
+ multiple={multiple}
53
+ onChange={handleChange}
54
+ className="dropin-input-file__input"
55
+ {...props}
56
+ />
57
+ </div>
58
+ );
59
+ };
@@ -0,0 +1,11 @@
1
+ /********************************************************************
2
+ * Copyright 2025 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ export * from '@adobe-commerce/elsie/components/InputFile/InputFile';
11
+ export { InputFile as default } from '@adobe-commerce/elsie/components/InputFile/InputFile';
@@ -9,23 +9,10 @@
9
9
 
10
10
  /* https://cssguidelin.es/#bem-like-naming */
11
11
 
12
- .dropin-product-item-card__skeleton {
13
- gap: var(--spacing-small);
14
- }
15
-
16
12
  .dropin-product-item-card__skeleton__image {
17
- height: 375px;
18
- }
19
-
20
- .dropin-product-item-card__skeleton__content {
21
- grid-column: 1/-1;
22
- }
23
-
24
- /* .dropin-product-item-card__skeleton__image {
25
13
  width: 100%;
26
- height: auto;
14
+ height: 370px;
27
15
  }
28
- */
29
16
 
30
17
  /* Medium (portrait tablets and large phones, 768px and up) */
31
18
  /* @media only screen and (min-width: 768px) { } */
@@ -19,10 +19,11 @@ export const ProductItemCardSkeleton: FunctionComponent = () => {
19
19
  fullWidth={true}
20
20
  className="dropin-product-item-card__skeleton__image"
21
21
  />
22
- <div className="dropin-product-item-card__content dropin-product-item-card__skeleton__content">
22
+ </Skeleton>
23
+ <Skeleton className="dropin-product-item-card__content dropin-product-item-card__skeleton__content">
23
24
  <SkeletonRow
24
25
  fullWidth={true}
25
- size="large"
26
+ size="xsmall"
26
27
  className="dropin-product-item-card__skeleton__item"
27
28
  />
28
29
  <SkeletonRow
@@ -32,11 +33,10 @@ export const ProductItemCardSkeleton: FunctionComponent = () => {
32
33
  />
33
34
  <SkeletonRow
34
35
  fullWidth={true}
35
- size="small"
36
+ size="xsmall"
36
37
  className="dropin-product-item-card__skeleton__item"
37
38
  />
38
- </div>{' '}
39
- </Skeleton>
39
+ </Skeleton>
40
40
  </div>
41
41
  );
42
42
  };
@@ -48,3 +48,4 @@ export * from '@adobe-commerce/elsie/components/Tag';
48
48
  export * from '@adobe-commerce/elsie/components/ContentGrid';
49
49
  export * from '@adobe-commerce/elsie/components/Pagination';
50
50
  export * from '@adobe-commerce/elsie/components/ProductItemCard';
51
+ export * from '@adobe-commerce/elsie/components/InputFile';