@cars4ever/public-ui 0.0.80

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.
@@ -0,0 +1,392 @@
1
+ import js from '@eslint/js';
2
+ import stylistic from '@stylistic/eslint-plugin';
3
+ import tsPlugin from '@typescript-eslint/eslint-plugin';
4
+ import tsParser from '@typescript-eslint/parser';
5
+ import importPlugin from 'eslint-plugin-import';
6
+ import jsxA11y from 'eslint-plugin-jsx-a11y';
7
+ import react from 'eslint-plugin-react';
8
+ import reactHooks from 'eslint-plugin-react-hooks';
9
+ import globals from 'globals';
10
+
11
+ const isProduction = process.env.NODE_ENV === 'production';
12
+
13
+ export default [
14
+ // Global ignores
15
+ {
16
+ ignores: ['**/*.js', '**/*.scss', 'dist/**'],
17
+ },
18
+
19
+ // TypeScript / TSX sources
20
+ {
21
+ files: ['src/**/*.{ts,tsx}'],
22
+
23
+ languageOptions: {
24
+ ecmaVersion: 2018,
25
+ sourceType: 'module',
26
+ parser: tsParser,
27
+ parserOptions: {
28
+ project: './tsconfig.json',
29
+ },
30
+ globals: {
31
+ ...globals.browser,
32
+ ...globals.commonjs,
33
+ ...globals.es2015,
34
+ ...globals.jest,
35
+ ...globals.node,
36
+ },
37
+ },
38
+
39
+ settings: {
40
+ react: { version: 'detect' },
41
+ 'import/resolver': {
42
+ typescript: { alwaysTryTypes: false },
43
+ },
44
+ },
45
+
46
+ plugins: {
47
+ '@stylistic': stylistic,
48
+ '@typescript-eslint': tsPlugin,
49
+ import: importPlugin,
50
+ 'jsx-a11y': jsxA11y,
51
+ react,
52
+ 'react-hooks': reactHooks,
53
+ },
54
+
55
+ rules: {
56
+ // ── ESLint recommended ─────────────────────────────────────────────
57
+ ...js.configs.recommended.rules,
58
+
59
+ // ── @typescript-eslint/eslint-recommended (turn off conflicting) ───
60
+ ...tsPlugin.configs['eslint-recommended'].overrides[0].rules,
61
+
62
+ // ── @typescript-eslint/recommended ────────────────────────────────
63
+ ...tsPlugin.configs.recommended.rules,
64
+
65
+ // ── eslint-plugin-import (errors + warnings + typescript) ─────────
66
+ ...importPlugin.configs.errors.rules,
67
+ ...importPlugin.configs.warnings.rules,
68
+ ...importPlugin.configs.typescript.rules,
69
+
70
+ // ── Formatting & style (@stylistic) ───────────────────────────────
71
+ '@stylistic/eol-last': ['error', 'always'],
72
+ '@stylistic/quotes': ['error', 'single'],
73
+ '@stylistic/indent': ['error', 2, { SwitchCase: 1 }],
74
+ '@stylistic/operator-linebreak': ['error', 'before'],
75
+ '@stylistic/comma-dangle': ['error', 'always-multiline'],
76
+ '@stylistic/multiline-ternary': ['error', 'always-multiline'],
77
+ '@stylistic/newline-per-chained-call': 'error',
78
+ '@stylistic/brace-style': 'error',
79
+ '@stylistic/object-property-newline': 'error',
80
+ '@stylistic/no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0 }],
81
+ '@stylistic/padded-blocks': ['error', 'never'],
82
+ '@stylistic/semi': 'error',
83
+ '@stylistic/no-extra-semi': 'error',
84
+ '@stylistic/max-len': [
85
+ 'error',
86
+ {
87
+ code: 120,
88
+ ignorePattern: '((const \\w+ = (<.+>)?\\((\\{)?.+(\\})?: .+\\):)|(texts\\..+))',
89
+ ignoreStrings: true,
90
+ ignoreComments: true,
91
+ ignoreTemplateLiterals: true,
92
+ ignoreRegExpLiterals: true,
93
+ },
94
+ ],
95
+ '@stylistic/key-spacing': 'error',
96
+ '@stylistic/comma-spacing': 'error',
97
+ '@stylistic/keyword-spacing': 'error',
98
+ '@stylistic/object-curly-spacing': ['error', 'always'],
99
+ '@stylistic/object-curly-newline': ['error', { ObjectExpression: { minProperties: 1 } }],
100
+ '@stylistic/function-call-argument-newline': ['error', 'consistent'],
101
+ '@stylistic/function-paren-newline': ['error', 'multiline'],
102
+ '@stylistic/function-call-spacing': ['error', 'never'],
103
+ '@stylistic/no-multi-spaces': 'error',
104
+ '@stylistic/no-trailing-spaces': 'error',
105
+ '@stylistic/padding-line-between-statements': [
106
+ 'error',
107
+ { blankLine: 'always', prev: 'block-like', next: '*' },
108
+ { blankLine: 'always', prev: 'const', next: 'block-like' },
109
+ ],
110
+ '@stylistic/space-in-parens': ['error', 'never'],
111
+ '@stylistic/array-bracket-newline': ['error', { multiline: true }],
112
+ '@stylistic/array-element-newline': ['error', 'consistent'],
113
+ '@stylistic/dot-location': ['warn', 'property'],
114
+ '@stylistic/new-parens': 'warn',
115
+ '@stylistic/no-extra-semi': 'error',
116
+ '@stylistic/no-mixed-operators': [
117
+ 'warn',
118
+ {
119
+ groups: [
120
+ ['&', '|', '^', '~', '<<', '>>', '>>>'],
121
+ ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
122
+ ['&&', '||'],
123
+ ['in', 'instanceof'],
124
+ ],
125
+ allowSamePrecedence: false,
126
+ },
127
+ ],
128
+ '@stylistic/no-whitespace-before-property': 'warn',
129
+ '@stylistic/rest-spread-spacing': ['warn', 'never'],
130
+
131
+ // ── Non-formatting rules ──────────────────────────────────────────
132
+ 'no-param-reassign': 'error',
133
+ 'no-nested-ternary': 'error',
134
+ 'no-unneeded-ternary': 'error',
135
+ curly: 'error',
136
+ 'arrow-body-style': ['error', 'as-needed'],
137
+ yoda: 'error',
138
+ 'no-object-constructor': 'warn',
139
+
140
+ // ── Import rules ──────────────────────────────────────────────────
141
+ 'import/default': 'off',
142
+ 'import/newline-after-import': 'warn',
143
+ 'import/no-cycle': isProduction ? 'error' : 'off',
144
+ 'import/order': [
145
+ 'warn',
146
+ {
147
+ 'newlines-between': 'always',
148
+ groups: ['external', 'builtin', 'internal', 'parent', 'sibling', 'index'],
149
+ pathGroups: [
150
+ { pattern: '^*', group: 'internal' },
151
+ { pattern: '^*/**/*', group: 'internal' },
152
+ ],
153
+ },
154
+ ],
155
+ 'import/no-unresolved': ['error', { ignore: ['.scss'] }],
156
+ 'import/first': 'error',
157
+ 'import/no-amd': 'error',
158
+ 'import/no-webpack-loader-syntax': 'error',
159
+
160
+ // ── @typescript-eslint rules ──────────────────────────────────────
161
+ '@typescript-eslint/no-explicit-any': 'off',
162
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
163
+ '@typescript-eslint/explicit-function-return-type': [
164
+ 'error',
165
+ { allowTypedFunctionExpressions: false },
166
+ ],
167
+ '@typescript-eslint/parameter-properties': 'off',
168
+ '@typescript-eslint/no-inferrable-types': 'off',
169
+ '@typescript-eslint/no-dynamic-delete': 'error',
170
+ '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
171
+ // typedef is deprecated with no replacement; enforces explicit type annotations
172
+ '@typescript-eslint/typedef': [
173
+ 'error',
174
+ {
175
+ arrowParameter: true,
176
+ parameter: true,
177
+ propertyDeclaration: true,
178
+ memberVariableDeclaration: false,
179
+ },
180
+ ],
181
+ '@typescript-eslint/naming-convention': [
182
+ 'error',
183
+ {
184
+ selector: 'interface',
185
+ format: ['PascalCase'],
186
+ custom: { regex: '^I[A-Z]', match: true },
187
+ },
188
+ ],
189
+ '@typescript-eslint/explicit-member-accessibility': 'error',
190
+ '@typescript-eslint/consistent-type-assertions': 'warn',
191
+ '@typescript-eslint/no-array-constructor': 'warn',
192
+ '@typescript-eslint/no-namespace': 'error',
193
+ '@typescript-eslint/no-use-before-define': [
194
+ 'warn',
195
+ { functions: false, classes: false, variables: false, typedefs: false },
196
+ ],
197
+ '@typescript-eslint/no-unused-vars': ['warn', { args: 'none', ignoreRestSiblings: true }],
198
+ '@typescript-eslint/no-useless-constructor': 'warn',
199
+ '@typescript-eslint/no-empty-object-type': 'off',
200
+
201
+ // ── React rules ───────────────────────────────────────────────────
202
+ 'react/boolean-prop-naming': [
203
+ 'error',
204
+ { rule: '^(is|are|has|have|with|no|hide|show|shrink)[A-Z]([A-Za-z0-9]?)+' },
205
+ ],
206
+ 'react/jsx-closing-bracket-location': 'error',
207
+ 'react/jsx-first-prop-new-line': ['error', 'multiline'],
208
+ 'react/jsx-max-props-per-line': ['error', { maximum: 1 }],
209
+ 'react/jsx-curly-spacing': ['error', { when: 'never' }],
210
+ 'react/jsx-equals-spacing': ['error', 'never'],
211
+ 'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
212
+ 'react/jsx-fragments': ['error', 'syntax'],
213
+ 'react/jsx-key': 'error',
214
+ 'react/jsx-newline': 'error',
215
+ 'react/jsx-no-literals': 'error',
216
+ 'react/jsx-no-useless-fragment': 'error',
217
+ 'react/jsx-one-expression-per-line': 'error',
218
+ 'react/jsx-props-no-multi-spaces': 'error',
219
+ 'react/jsx-tag-spacing': ['error', { beforeClosing: 'never' }],
220
+ 'react/jsx-wrap-multilines': [
221
+ 'error',
222
+ {
223
+ declaration: 'parens-new-line',
224
+ assignment: 'parens-new-line',
225
+ return: 'parens-new-line',
226
+ arrow: 'parens-new-line',
227
+ condition: 'parens-new-line',
228
+ logical: 'parens-new-line',
229
+ prop: 'parens-new-line',
230
+ },
231
+ ],
232
+ 'react/destructuring-assignment': ['error', 'always'],
233
+ 'react/no-multi-comp': ['error'],
234
+ 'react/self-closing-comp': ['error'],
235
+ 'react/jsx-boolean-value': 'error',
236
+ 'react/jsx-closing-tag-location': 'error',
237
+ 'react/jsx-curly-brace-presence': 'error',
238
+ 'react/jsx-curly-newline': ['error', 'consistent'],
239
+ 'react/jsx-uses-react': 'off',
240
+ 'react/jsx-uses-vars': 'warn',
241
+ 'react/no-danger-with-children': 'warn',
242
+ 'react/no-direct-mutation-state': 'warn',
243
+ 'react/no-is-mounted': 'warn',
244
+ 'react/no-typos': 'error',
245
+ 'react/react-in-jsx-scope': 'off',
246
+ 'react/require-render-return': 'error',
247
+ 'react/style-prop-object': 'warn',
248
+ 'react/forbid-foreign-prop-types': ['warn', { allowInPropTypes: true }],
249
+ 'react/jsx-no-comment-textnodes': 'warn',
250
+ 'react/jsx-no-duplicate-props': 'warn',
251
+ 'react/jsx-no-target-blank': 'warn',
252
+ 'react/jsx-no-undef': 'error',
253
+ 'react/jsx-pascal-case': ['warn', { allowAllCaps: true, ignore: [] }],
254
+
255
+ // ── React Hooks ───────────────────────────────────────────────────
256
+ 'react-hooks/rules-of-hooks': 'error',
257
+ 'react-hooks/exhaustive-deps': 'warn',
258
+
259
+ // ── jsx-a11y rules ────────────────────────────────────────────────
260
+ 'jsx-a11y/alt-text': 'warn',
261
+ 'jsx-a11y/anchor-is-valid': ['warn', { aspects: ['noHref', 'invalidHref'] }],
262
+ 'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
263
+ 'jsx-a11y/aria-props': 'warn',
264
+ 'jsx-a11y/aria-proptypes': 'warn',
265
+ 'jsx-a11y/aria-role': 'warn',
266
+ 'jsx-a11y/aria-unsupported-elements': 'warn',
267
+ 'jsx-a11y/heading-has-content': 'warn',
268
+ 'jsx-a11y/iframe-has-title': 'warn',
269
+ 'jsx-a11y/img-redundant-alt': 'warn',
270
+ 'jsx-a11y/no-access-key': 'warn',
271
+ 'jsx-a11y/no-distracting-elements': 'warn',
272
+ 'jsx-a11y/no-redundant-roles': 'warn',
273
+ 'jsx-a11y/role-has-required-aria-props': 'warn',
274
+ 'jsx-a11y/role-supports-aria-props': 'warn',
275
+ 'jsx-a11y/scope': 'warn',
276
+
277
+ // ── Miscellaneous ─────────────────────────────────────────────────
278
+ 'no-console': ['warn', { allow: ['warn', 'info', 'error'] }],
279
+ eqeqeq: 'error',
280
+ 'new-parens': 'warn',
281
+ 'no-caller': 'warn',
282
+ 'no-cond-assign': ['warn', 'except-parens'],
283
+ 'no-const-assign': 'warn',
284
+ 'no-control-regex': 'warn',
285
+ 'no-delete-var': 'warn',
286
+ 'no-dupe-args': 'warn',
287
+ 'no-dupe-keys': 'warn',
288
+ 'no-duplicate-case': 'warn',
289
+ 'no-empty-character-class': 'warn',
290
+ 'no-empty-pattern': 'warn',
291
+ 'no-eval': 'warn',
292
+ 'no-ex-assign': 'warn',
293
+ 'no-extend-native': 'warn',
294
+ 'no-extra-bind': 'warn',
295
+ 'no-extra-label': 'warn',
296
+ 'no-fallthrough': 'warn',
297
+ 'no-func-assign': 'warn',
298
+ 'no-implied-eval': 'warn',
299
+ 'no-invalid-regexp': 'warn',
300
+ 'no-iterator': 'warn',
301
+ 'no-label-var': 'warn',
302
+ 'no-labels': ['warn', { allowLoop: true, allowSwitch: false }],
303
+ 'no-lone-blocks': 'warn',
304
+ 'no-loop-func': 'warn',
305
+ 'no-multi-str': 'warn',
306
+ 'no-global-assign': 'warn',
307
+ 'no-unsafe-negation': 'warn',
308
+ 'no-new-func': 'warn',
309
+ 'no-new-wrappers': 'warn',
310
+ 'no-obj-calls': 'warn',
311
+ 'no-octal': 'warn',
312
+ 'no-octal-escape': 'warn',
313
+ 'no-redeclare': 'warn',
314
+ 'no-regex-spaces': 'warn',
315
+ 'no-restricted-syntax': ['warn', 'WithStatement'],
316
+ 'no-script-url': 'warn',
317
+ 'no-self-assign': 'warn',
318
+ 'no-self-compare': 'warn',
319
+ 'no-sequences': 'warn',
320
+ 'no-shadow-restricted-names': 'warn',
321
+ 'no-sparse-arrays': 'warn',
322
+ 'no-template-curly-in-string': 'warn',
323
+ 'no-this-before-super': 'warn',
324
+ 'no-throw-literal': 'warn',
325
+ 'no-restricted-globals': [
326
+ 'error',
327
+ 'addEventListener', 'blur', 'close', 'closed', 'confirm', 'defaultStatus',
328
+ 'defaultstatus', 'event', 'external', 'find', 'focus', 'frameElement',
329
+ 'frames', 'history', 'innerHeight', 'innerWidth', 'length', 'location',
330
+ 'locationbar', 'menubar', 'moveBy', 'moveTo', 'name', 'onblur', 'onerror',
331
+ 'onfocus', 'onload', 'onresize', 'onunload', 'open', 'opener', 'opera',
332
+ 'outerHeight', 'outerWidth', 'pageXOffset', 'pageYOffset', 'parent',
333
+ 'print', 'removeEventListener', 'resizeBy', 'resizeTo', 'screen',
334
+ 'screenLeft', 'screenTop', 'screenX', 'screenY', 'scroll', 'scrollbars',
335
+ 'scrollBy', 'scrollTo', 'scrollX', 'scrollY', 'self', 'status',
336
+ 'statusbar', 'stop', 'toolbar', 'top',
337
+ ],
338
+ 'no-unexpected-multiline': 'warn',
339
+ 'no-unreachable': 'warn',
340
+ 'no-unused-expressions': [
341
+ 'error',
342
+ { allowShortCircuit: true, allowTernary: true, allowTaggedTemplates: true },
343
+ ],
344
+ 'no-unused-labels': 'warn',
345
+ 'no-useless-computed-key': 'warn',
346
+ 'no-useless-concat': 'warn',
347
+ 'no-useless-escape': 'warn',
348
+ 'no-useless-rename': [
349
+ 'warn',
350
+ { ignoreDestructuring: false, ignoreImport: false, ignoreExport: false },
351
+ ],
352
+ 'no-with': 'warn',
353
+ 'require-yield': 'warn',
354
+ strict: ['warn', 'never'],
355
+ 'unicode-bom': ['warn', 'never'],
356
+ 'use-isnan': 'warn',
357
+ 'valid-typeof': 'warn',
358
+ 'no-restricted-properties': [
359
+ 'error',
360
+ { object: 'require', property: 'ensure', message: 'Please use import() instead.' },
361
+ { object: 'System', property: 'import', message: 'Please use import() instead.' },
362
+ ],
363
+ 'getter-return': 'warn',
364
+
365
+ // ── Disabled rules (superseded by TS equivalents) ─────────────────
366
+ 'default-case': 'off',
367
+ 'no-dupe-class-members': 'off',
368
+ 'no-undef': 'off',
369
+ 'no-array-constructor': 'off',
370
+ 'no-use-before-define': 'off',
371
+ 'no-unused-vars': 'off',
372
+ 'no-useless-constructor': 'off',
373
+ },
374
+ },
375
+
376
+ // Override: src/types/*.ts — disable semi (interface closing brace false-positive)
377
+ {
378
+ files: ['src/types/*.ts'],
379
+ rules: {
380
+ '@stylistic/semi': 'off',
381
+ },
382
+ },
383
+
384
+ // Override: sagas.ts
385
+ {
386
+ files: ['sagas.ts'],
387
+ rules: {
388
+ '@typescript-eslint/explicit-function-return-type': 'off',
389
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
390
+ },
391
+ },
392
+ ];
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@cars4ever/public-ui",
3
+ "version": "0.0.80",
4
+ "description": "Wismo public ui components",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "sideEffects": [
10
+ "*.*(s)css"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://bitbucket.org/interdan/public-ui/"
18
+ },
19
+ "scripts": {
20
+ "build": "yarn clean && NODE_ENV=production tsup",
21
+ "postbuild": "cp -r src/assets dist/",
22
+ "clean": "rimraf dist",
23
+ "prepare": "husky || true",
24
+ "postinstall": "ts-patch install -s",
25
+ "release:patch": "yarn build && yarn publish --new-version patch",
26
+ "release:minor": "yarn build && yarn publish --new-version minor",
27
+ "release:major": "yarn build && yarn publish --new-version major",
28
+ "lint:styles": "stylelint src --max-warnings=0",
29
+ "lint:code": "eslint \"src/**/*.{ts,tsx}\" --max-warnings=0",
30
+ "lint": "run-p lint:code lint:styles",
31
+ "storybook": "storybook dev -p 6006",
32
+ "build-storybook": "storybook build"
33
+ },
34
+ "author": "interdan",
35
+ "license": "MIT",
36
+ "devDependencies": {
37
+ "@storybook/addon-docs": "^10.3.6",
38
+ "@storybook/react-vite": "^10.3.6",
39
+ "@stylistic/eslint-plugin": "^5.10.0",
40
+ "@types/lodash": "^4",
41
+ "@types/lodash-es": "^4.17.12",
42
+ "@types/react": "^19.1.0",
43
+ "@types/react-dom": "^19.1.0",
44
+ "@typescript-eslint/eslint-plugin": "^8.59.2",
45
+ "@typescript-eslint/parser": "^8.59.2",
46
+ "@vitejs/plugin-react": "^6.0.1",
47
+ "date-fns": "^4.1.0",
48
+ "esbuild": "^0.28.0",
49
+ "esbuild-sass-plugin": "^3.7.0",
50
+ "eslint": "^9.39.4",
51
+ "eslint-import-resolver-typescript": "^4.4.4",
52
+ "eslint-plugin-import": "^2.32.0",
53
+ "eslint-plugin-jsx-a11y": "^6.10.2",
54
+ "eslint-plugin-react": "^7.37.5",
55
+ "eslint-plugin-react-hooks": "^7.1.1",
56
+ "husky": "^9.1.7",
57
+ "lodash": "^4.18.1",
58
+ "npm-run-all2": "^8.0.4",
59
+ "postcss": "^8.5.14",
60
+ "react": "^19.1.0",
61
+ "react-content-loader": "^7.1.2",
62
+ "react-dom": "^19.1.0",
63
+ "react-hook-form": "^7.75.0",
64
+ "rimraf": "^6.1.3",
65
+ "sass": "^1.99.0",
66
+ "storybook": "^10.3.6",
67
+ "stylelint": "^17.11.0",
68
+ "stylelint-config-sass-guidelines": "^13.0.0",
69
+ "stylelint-order": "^8.1.1",
70
+ "ts-patch": "^4.0.1",
71
+ "tsup": "^8.5.1",
72
+ "typescript": "^5.8.3",
73
+ "typescript-transform-paths": "^3.5.6",
74
+ "vite": "^8.0.11"
75
+ },
76
+ "peerDependencies": {
77
+ "date-fns": "^4.1.0",
78
+ "react": "^19.0.0",
79
+ "react-content-loader": "^7.1.2",
80
+ "react-dom": "^19.0.0",
81
+ "react-hook-form": "^7.0.0"
82
+ },
83
+ "dependencies": {
84
+ "@cars4ever/media-utils": "^0.0.19",
85
+ "classnames": "^2.5.1",
86
+ "imask": "^7.6.1",
87
+ "lodash-es": "^4.17.21",
88
+ "rc-slider": "^11.1.9",
89
+ "react-imask": "^7.6.1",
90
+ "react-loader-spinner": "^8.0.2",
91
+ "react-select": "^5.10.2",
92
+ "react-textarea-autosize": "^8.5.9",
93
+ "ssr-window": "^5.0.1"
94
+ },
95
+ "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
96
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,66 @@
1
+ import { defineConfig } from 'tsup';
2
+ import { sassPlugin } from 'esbuild-sass-plugin';
3
+ import { resolve } from 'path';
4
+
5
+ const SCSS_ALIAS_ROOT = resolve(process.cwd(), 'src/assets/scss');
6
+
7
+ export default defineConfig({
8
+ entry: ['src/index.ts'],
9
+ format: ['esm'],
10
+ target: 'es2020',
11
+ dts: true,
12
+ clean: true,
13
+ minify: true,
14
+ splitting: true,
15
+ outDir: 'dist',
16
+ esbuildPlugins: [
17
+ // CSS Modules (.module.scss) — scoped class names
18
+ sassPlugin({
19
+ filter: /\.module\.scss$/,
20
+ type: 'local-css',
21
+ importMapper: (url: string) => {
22
+ if (url.startsWith('^styles/')) {
23
+ const assetPath = url.replace('^styles/', '');
24
+ const resolved = resolve(SCSS_ALIAS_ROOT, assetPath);
25
+
26
+ return resolved.endsWith('.scss') ? resolved : `${resolved}.scss`;
27
+ }
28
+
29
+ return url;
30
+ },
31
+ }),
32
+ // Global SCSS — e.g. ThemeProvider's `import '^styles/globals'`
33
+ // (resolved by tsconfig paths to src/assets/scss/globals.scss)
34
+ sassPlugin({
35
+ filter: /\.scss$/,
36
+ type: 'css',
37
+ importMapper: (url: string) => {
38
+ if (url.startsWith('^styles/')) {
39
+ const assetPath = url.replace('^styles/', '');
40
+ const resolved = resolve(SCSS_ALIAS_ROOT, assetPath);
41
+
42
+ return resolved.endsWith('.scss') ? resolved : `${resolved}.scss`;
43
+ }
44
+
45
+ return url;
46
+ },
47
+ }),
48
+ ],
49
+ esbuildOptions(options) {
50
+ options.alias = {
51
+ '^enums': resolve('src/enums'),
52
+ '^types': resolve('src/types'),
53
+ '^utils': resolve('src/utils'),
54
+ '^icons': resolve('src/icons'),
55
+ '^configs': resolve('src/configs'),
56
+ '^hooks': resolve('src/hooks'),
57
+ '^inputs': resolve('src/inputs'),
58
+ '^controls': resolve('src/controls'),
59
+ '^forms': resolve('src/forms'),
60
+ '^feedback': resolve('src/feedback'),
61
+ '^data-display': resolve('src/data-display'),
62
+ '^layout': resolve('src/layout'),
63
+ '^common': resolve('src/common'),
64
+ };
65
+ },
66
+ });