@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.48 → 2.0.0-next.49

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 (43) hide show
  1. package/.storybook/ComponentPreview.tsx +26 -0
  2. package/.storybook/PreviewTemplate.tsx +99 -0
  3. package/.storybook/action-handler.ts +81 -0
  4. package/.storybook/channels.ts +44 -0
  5. package/.storybook/main.ts +313 -0
  6. package/.storybook/manager.ts +71 -0
  7. package/.storybook/openbridgeTheme.ts +197 -0
  8. package/.storybook/preview-head.html +15 -0
  9. package/.storybook/preview.tsx +129 -0
  10. package/.storybook/vitest.setup.ts +23 -0
  11. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  12. package/custom-elements.json +7 -1
  13. package/dist/components/icon-button/icon-button.d.ts +4 -0
  14. package/dist/components/icon-button/icon-button.d.ts.map +1 -1
  15. package/dist/components/icon-button/icon-button.js.map +1 -1
  16. package/eslint.config.mjs +589 -0
  17. package/fix-imports.mjs +185 -0
  18. package/fix-js-extensions.mjs +44 -0
  19. package/lit-localize.json +15 -0
  20. package/new-component.ts +148 -0
  21. package/package.json +55 -3
  22. package/postcss.config.mjs +195 -0
  23. package/script/check-css-mixins.ts +191 -0
  24. package/script/check-css-variables.ts +280 -0
  25. package/script/convert-icons.ts +202 -0
  26. package/script/convert-vessel-svg-to-ts.ts +110 -0
  27. package/script/docgen/README.md +95 -0
  28. package/script/docgen/docs-gen.ts +225 -0
  29. package/script/docgen/prompt-system.txt +187 -0
  30. package/script/download-alert-icons.ts +193 -0
  31. package/script/download-icons.ts +314 -0
  32. package/script/figmavariables.json +139 -0
  33. package/script/generate-bundle-entry.ts +77 -0
  34. package/script/prepare-full-bundle.ts +105 -0
  35. package/script/sort-custom-element-manifest.ts +67 -0
  36. package/src/components/icon-button/icon-button.ts +4 -0
  37. package/vite.config.ts +107 -0
  38. package/vitest.browser.config.ts +14 -0
  39. package/vitest.config.ts +51 -0
  40. package/xliff/es-419.xlf +111 -0
  41. package/xliff/fi-FI.xlf +139 -0
  42. package/dist/NotoSans.ttf +0 -0
  43. package/dist/oicl.svg +0 -4
@@ -0,0 +1,185 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import {fileURLToPath} from 'url';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ // Parse command line arguments
9
+ const args = process.argv.slice(2);
10
+ const isDryRun = args.includes('--dry-run') || args.includes('-d');
11
+ const isVerbose = args.includes('--verbose') || args.includes('-v');
12
+
13
+ if (args.includes('--help') || args.includes('-h')) {
14
+ console.log(`
15
+ Usage: node fix-imports.mjs [options]
16
+
17
+ Options:
18
+ --dry-run, -d Show what would be changed without making changes
19
+ --verbose, -v Show detailed output
20
+ --help, -h Show this help message
21
+
22
+ Examples:
23
+ node fix-imports.mjs # Fix all imports
24
+ node fix-imports.mjs --dry-run # Check imports without changing files
25
+ node fix-imports.mjs -d -v # Dry run with verbose output
26
+ `);
27
+ process.exit(0);
28
+ }
29
+
30
+ // Function to recursively find all .ts files
31
+ function findTsFiles(dir, files = []) {
32
+ const items = fs.readdirSync(dir);
33
+
34
+ for (const item of items) {
35
+ const fullPath = path.join(dir, item);
36
+ const stat = fs.statSync(fullPath);
37
+
38
+ if (
39
+ stat.isDirectory() &&
40
+ !item.startsWith('.') &&
41
+ item !== 'node_modules' &&
42
+ item !== 'dist'
43
+ ) {
44
+ findTsFiles(fullPath, files);
45
+ } else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
46
+ files.push(fullPath);
47
+ }
48
+ }
49
+
50
+ return files;
51
+ }
52
+
53
+ // Function to check/fix imports in a file
54
+ function processImportsInFile(filePath) {
55
+ const content = fs.readFileSync(filePath, 'utf8');
56
+ let modified = false;
57
+ const changes = [];
58
+
59
+ // Fix relative imports with 'from' that don't have extensions
60
+ let fixedContent = content.replace(
61
+ /import\s+([^'"]*)\s+from\s+['"](\.[^'"]*?)(?<!\.ts|\.js|\.css|\.json|\.vue|\.mjs)['"];?/g,
62
+ (match, importPart, importPath, offset) => {
63
+ // Skip CSS imports with ?inline
64
+ if (importPath.includes('.css?inline')) {
65
+ return match;
66
+ }
67
+
68
+ // Check if the imported file exists with .ts extension (source file)
69
+ const resolvedPath = path.resolve(
70
+ path.dirname(filePath),
71
+ importPath + '.ts'
72
+ );
73
+ if (fs.existsSync(resolvedPath)) {
74
+ const lineNumber = content.substring(0, offset).split('\n').length;
75
+ const newImport = `import ${importPart} from '${importPath}.js';`;
76
+ changes.push({
77
+ line: lineNumber,
78
+ old: match,
79
+ new: newImport,
80
+ type: 'import-from',
81
+ });
82
+ modified = true;
83
+ return newImport;
84
+ }
85
+
86
+ return match;
87
+ }
88
+ );
89
+
90
+ // Fix side-effect imports without 'from' that don't have extensions
91
+ fixedContent = fixedContent.replace(
92
+ /import\s+['"](\.[^'"]*?)(?<!\.ts|\.js|\.css|\.json|\.vue|\.mjs)['"];?/g,
93
+ (match, importPath, offset) => {
94
+ // Skip CSS imports with ?inline
95
+ if (importPath.includes('.css?inline')) {
96
+ return match;
97
+ }
98
+
99
+ // Check if the imported file exists with .ts extension (source file)
100
+ const resolvedPath = path.resolve(
101
+ path.dirname(filePath),
102
+ importPath + '.ts'
103
+ );
104
+ if (fs.existsSync(resolvedPath)) {
105
+ const lineNumber = content.substring(0, offset).split('\n').length;
106
+ const newImport = `import '${importPath}.js';`;
107
+ changes.push({
108
+ line: lineNumber,
109
+ old: match,
110
+ new: newImport,
111
+ type: 'import-side-effect',
112
+ });
113
+ modified = true;
114
+ return newImport;
115
+ }
116
+
117
+ return match;
118
+ }
119
+ );
120
+
121
+ const relativePath = path.relative(__dirname, filePath);
122
+
123
+ if (modified) {
124
+ if (isDryRun) {
125
+ console.log(`❌ ${relativePath} - would be modified`);
126
+ if (isVerbose) {
127
+ changes.forEach((change) => {
128
+ console.log(` Line ${change.line}: ${change.old} → ${change.new}`);
129
+ });
130
+ }
131
+ } else {
132
+ fs.writeFileSync(filePath, fixedContent, 'utf8');
133
+ console.log(`✅ Fixed imports in: ${relativePath}`);
134
+ if (isVerbose) {
135
+ changes.forEach((change) => {
136
+ console.log(` Line ${change.line}: ${change.old} → ${change.new}`);
137
+ });
138
+ }
139
+ }
140
+ } else if (isVerbose) {
141
+ console.log(`✅ ${relativePath} - no changes needed`);
142
+ }
143
+
144
+ return {modified, changes: changes.length};
145
+ }
146
+
147
+ // Main execution
148
+ const srcDir = path.join(__dirname, 'src');
149
+ const tsFiles = findTsFiles(srcDir);
150
+
151
+ console.log(`Found ${tsFiles.length} TypeScript files`);
152
+ if (isDryRun) {
153
+ console.log('🔍 Running in dry-run mode - no files will be modified\n');
154
+ }
155
+
156
+ let totalFilesModified = 0;
157
+ let totalChanges = 0;
158
+
159
+ for (const file of tsFiles) {
160
+ const result = processImportsInFile(file);
161
+ if (result.modified) {
162
+ totalFilesModified++;
163
+ }
164
+ totalChanges += result.changes;
165
+ }
166
+
167
+ console.log('\n📊 Summary:');
168
+ console.log(`Files processed: ${tsFiles.length}`);
169
+ console.log(
170
+ `Files ${isDryRun ? 'that would be modified' : 'modified'}: ${totalFilesModified}`
171
+ );
172
+ console.log(`Total changes ${isDryRun ? 'needed' : 'made'}: ${totalChanges}`);
173
+
174
+ if (isDryRun && totalFilesModified > 0) {
175
+ console.log(
176
+ '\n❌ Some files need import fixes. Run without --dry-run to fix them.'
177
+ );
178
+ process.exit(1);
179
+ } else if (isDryRun) {
180
+ console.log('\n✅ All imports have correct file extensions!');
181
+ } else if (totalFilesModified > 0) {
182
+ console.log('\n✅ All imports have been fixed!');
183
+ } else {
184
+ console.log('\n✅ All imports already had correct file extensions!');
185
+ }
@@ -0,0 +1,44 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const SRC_DIR = path.resolve('src');
5
+ const IMPORT_REGEX = /import(.+?)['"](\.*\/[^'";?]+)['"]/g; // Skip filenames with ?
6
+
7
+ function checkAndFixFile(filePath) {
8
+ let content = fs.readFileSync(filePath, 'utf8');
9
+ let hasFixes = false;
10
+
11
+ content = content.replace(IMPORT_REGEX, (fullMatch, middelPart, importPath) => {
12
+ if (!importPath.endsWith('.js')) {
13
+ hasFixes = true;
14
+ return `import${middelPart}'${importPath}.js'`;
15
+ }
16
+ return fullMatch;
17
+ });
18
+
19
+ if (hasFixes) {
20
+ fs.writeFileSync(filePath, content, 'utf8');
21
+ console.log(`🔧 Fixed imports in: ${filePath}`);
22
+ }
23
+ }
24
+
25
+ function getAllTsFiles(dir) {
26
+ let files = [];
27
+ for (const file of fs.readdirSync(dir)) {
28
+ const fullPath = path.join(dir, file);
29
+ if (fs.statSync(fullPath).isDirectory()) {
30
+ files = files.concat(getAllTsFiles(fullPath));
31
+ } else if (file.endsWith('.ts')) {
32
+ files.push(fullPath);
33
+ }
34
+ }
35
+ return files;
36
+ }
37
+
38
+ function main() {
39
+ const tsFiles = getAllTsFiles(SRC_DIR);
40
+ tsFiles.forEach(file => checkAndFixFile(file));
41
+ console.log('✅ All imports are now correctly formatted.');
42
+ }
43
+
44
+ main();
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/lit/lit/main/packages/localize-tools/config.schema.json",
3
+ "sourceLocale": "en",
4
+ "targetLocales": ["es-419", "fi-FI"],
5
+ "tsConfig": "./tsconfig.json",
6
+ "output": {
7
+ "mode": "runtime",
8
+ "outputDir": "./src/generated/locales",
9
+ "localeCodesModule": "./src/generated/locale-codes.ts"
10
+ },
11
+ "interchange": {
12
+ "format": "xliff",
13
+ "xliffDir": "./xliff/"
14
+ }
15
+ }
@@ -0,0 +1,148 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ import {question, select, multiselect} from '@topcli/prompts';
5
+
6
+ const name = await question(
7
+ 'Component name (without obc prefix, and UpperCamelCase) ?',
8
+ {
9
+ validators: [
10
+ {
11
+ validate: (value) => /^[A-Z][a-zA-Z0-9]+$/.test(value),
12
+ message: 'Component name must be UpperCamelCase',
13
+ },
14
+ {
15
+ message: 'Component name is required',
16
+ validate: (value) => !!value,
17
+ },
18
+ ],
19
+ }
20
+ );
21
+ const componentType = await select('Type of component', {
22
+ choices: [
23
+ 'ui (input, label, tables)',
24
+ 'instrument (compass, azimuth)',
25
+ 'indicator (bearing, speed, rot)',
26
+ 'page',
27
+ 'ar',
28
+ 'automation',
29
+ 'integration system',
30
+ 'building-block',
31
+ 'bars-graphs (line, area, donut, pie)',
32
+ ],
33
+ });
34
+ const files = await multiselect('Create files', {
35
+ choices: ['css', 'storybook'],
36
+ preSelectedChoices: ['css', 'storybook'],
37
+ });
38
+
39
+ // Convert name to kebab-case
40
+ const componentName = name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
41
+
42
+ let parentDir: string;
43
+ if (componentType === 'ui (input, label, tables)') {
44
+ parentDir = 'components';
45
+ } else if (componentType === 'indicator (bearing, speed, rot)') {
46
+ parentDir = 'navigation-instruments';
47
+ } else if (componentType === 'instrument (compass, azimuth)') {
48
+ parentDir = 'navigation-instruments';
49
+ } else if (componentType === 'ar') {
50
+ parentDir = 'ar';
51
+ } else if (componentType === 'automation') {
52
+ parentDir = 'automation';
53
+ } else if (componentType === 'page') {
54
+ parentDir = 'pages';
55
+ } else if (componentType === 'building-block') {
56
+ parentDir = 'building-blocks';
57
+ } else if (componentType === 'integration system') {
58
+ parentDir = 'integration-systems';
59
+ } else if (componentType === 'bars-graphs (line, area, donut, pie)') {
60
+ parentDir = 'bars-graphs';
61
+ } else {
62
+ throw new Error('Invalid component type');
63
+ }
64
+ const dir = path.join('src', parentDir, componentName);
65
+ // Create directory
66
+ fs.mkdirSync(dir, {recursive: true});
67
+
68
+ // Create files
69
+ // Create lit file
70
+ const hasCss = files.includes('css');
71
+ const litFile = path.join(dir, `${componentName}.ts`);
72
+ const content = `import {LitElement, html${hasCss ? `, unsafeCSS` : ``}} from 'lit';
73
+ import {customElement} from '../../decorator.js';
74
+ ${hasCss ? `import componentStyle from './${componentName}.css?inline';` : ''}
75
+
76
+ @customElement('obc-${componentName}')
77
+ export class Obc${name} extends LitElement {
78
+
79
+ override render() {
80
+ return html\`
81
+ <div class="wrapper">
82
+ </div>
83
+ \`;
84
+ }
85
+
86
+ ${hasCss ? ` static override styles = unsafeCSS(componentStyle);` : ''}
87
+ }
88
+
89
+ declare global {
90
+ interface HTMLElementTagNameMap {
91
+ 'obc-${componentName}': Obc${name};
92
+ }
93
+ }
94
+ `;
95
+ fs.writeFileSync(litFile, content);
96
+
97
+ // Create css file
98
+ if (files.includes('css')) {
99
+ const cssFile = path.join(dir, `${componentName}.css`);
100
+ const content = ``;
101
+ fs.writeFileSync(cssFile, content);
102
+ }
103
+
104
+ // Create storybook file
105
+ if (files.includes('storybook')) {
106
+ let storybookGroup = '';
107
+ if (componentType === 'ar') {
108
+ storybookGroup = 'AR';
109
+ } else if (componentType === 'automation') {
110
+ storybookGroup = 'Automation';
111
+ } else if (componentType === 'building-block') {
112
+ storybookGroup = 'Building Blocks';
113
+ } else if (componentType === 'page') {
114
+ storybookGroup = 'Pages';
115
+ } else if (componentType === 'integration system') {
116
+ storybookGroup = 'Integration Systems';
117
+ } else if (componentType === 'indicator (bearing, speed, rot)') {
118
+ storybookGroup = 'Indicators';
119
+ } else if (componentType === 'instrument (compass, azimuth)') {
120
+ storybookGroup = 'Instruments';
121
+ } else if (componentType === 'bars-graphs (line, area, donut, pie)') {
122
+ storybookGroup = 'Bars and Graphs';
123
+ } else {
124
+ storybookGroup = await question('Storybook group ');
125
+ }
126
+ const storybookTitle = await question('Storybook title ');
127
+ const storybookFile = path.join(dir, `${componentName}.stories.ts`);
128
+ const content = `import type {Meta, StoryObj} from '@storybook/web-components-vite';
129
+ import {Obc${name}} from './${componentName}.js';
130
+ import './${componentName}.js';
131
+
132
+ const meta: Meta<typeof Obc${name}> = {
133
+ title: '${storybookGroup}/${storybookTitle}',
134
+ tags: ['autodocs', '6.0'],
135
+ component: 'obc-${componentName}',
136
+ args: {
137
+ },
138
+ } satisfies Meta<Obc${name}>;
139
+
140
+ export default meta;
141
+ type Story = StoryObj<Obc${name}>;
142
+
143
+ export const Primary: Story = {
144
+ args: {
145
+ },
146
+ };`;
147
+ fs.writeFileSync(storybookFile, content);
148
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oicl/openbridge-webcomponents-full-bundle",
3
- "version": "2.0.0-next.48",
3
+ "version": "2.0.0-next.49",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -93,10 +93,22 @@
93
93
  "!dist/companylogo-day.png",
94
94
  "bundle/openbridge-webcomponents.bundle.js",
95
95
  "bundle/openbridge-webcomponents.bundle.js.map",
96
+ ".storybook",
97
+ "script",
98
+ "xliff",
99
+ "src",
100
+ "docs",
96
101
  "custom-elements.json",
97
102
  "tsconfig.json",
98
- "src",
99
- "docs"
103
+ "eslint.config.mjs",
104
+ "vite.config.ts",
105
+ "postcss.config.mjs",
106
+ "lit-localize.json",
107
+ "new-component.ts",
108
+ "fix-imports.mjs",
109
+ "fix-js-extensions.mjs",
110
+ "vitest.browser.config.ts",
111
+ "vitest.config.ts"
100
112
  ],
101
113
  "publishConfig": {
102
114
  "access": "public"
@@ -104,5 +116,45 @@
104
116
  "customElements": "custom-elements.json",
105
117
  "overrides": {
106
118
  "storybook": "$storybook"
119
+ },
120
+ "scripts": {
121
+ "👷_BUILD_____________________________________________________": "echo _____",
122
+ "build": "npm run build:translations && npm run build:ts",
123
+ "build:ts": "vite build",
124
+ "build:ts:watch": "vite build --watch",
125
+ "build:bundle": "tsx ./script/generate-bundle-entry.ts && vite build --mode bundle",
126
+ "build:translations": "lit localize build",
127
+ "prepack": "npm run build && npm run build:bundle && npm run analyze",
128
+ "📚_STORYBOOK_________________________________________________": "echo _____",
129
+ "storybook": "npm run analyze && storybook dev -p 6006 --no-open",
130
+ "test-storybook": "vitest --project=storybook",
131
+ "test-storybook:watch": "vitest --project=storybook --watch",
132
+ "update-snapshots": "rm -rf __vis__/linux/__baselines__ && mv __vis__/linux/__results__/ __vis__/linux/__baselines__/",
133
+ "build-storybook": "storybook build",
134
+ "storybook:server": "http-server -p 6006 storybook-static",
135
+ "preview": "vite preview",
136
+ "prebuild-storybook": "npm run build:translations",
137
+ "🧩_COMPONENT_________________________________________________": "echo _____",
138
+ "new:component": "tsx ./new-component.ts",
139
+ "🧪_CHECKS____________________________________________________": "echo _____",
140
+ "typecheck": "tsc --noEmit",
141
+ "format": "prettier \"**/*.{cjs,html,js,json,md,ts,css}\" --write",
142
+ "format:check": "prettier \"**/*.{cjs,html,js,json,md,ts,css}\" --check",
143
+ "lint": "npm run lint:mixins && npm run lint:variables && npm run lint:lit-analyzer && npm run lint:eslint",
144
+ "lint:mixins": "tsx ./script/check-css-mixins.ts",
145
+ "lint:variables": "tsx ./script/check-css-variables.ts",
146
+ "lint:eslint": "eslint 'src/**/*.ts'",
147
+ "lint:lit-analyzer": "lit-analyzer --strict --maxWarnings 0",
148
+ "fix-imports": "node fix-imports.mjs",
149
+ "fix-imports:check": "node fix-imports.mjs --dry-run",
150
+ "test:browser": "vitest --config=vitest.browser.config.ts",
151
+ "📦_WRAPPERS__________________________________________________": "echo _____",
152
+ "📜_SCRIPTS___________________________________________________": "echo _____",
153
+ "download:icons": "tsx ./script/download-icons.ts",
154
+ "analyze": "cem analyze --litelement --globs \"src/**/*.ts\" --exclude \"src/**/*.stories.ts\" && tsx ./script/sort-custom-element-manifest.ts",
155
+ "analyze:watch": "cem analyze --litelement --globs \"src/**/*.ts\" --exclude \"src/**/*.stories.ts\" --watch",
156
+ "clean": "rm -rf node_modules dist bundle custom-elements.json",
157
+ "言_TRANSLATIONS______________________________________________": "echo _____",
158
+ "translations:extract": "lit localize extract"
107
159
  }
108
160
  }
@@ -0,0 +1,195 @@
1
+ import path from 'path';
2
+ import postcssMixins from 'postcss-mixins';
3
+ import postcssNesting from 'postcss-nesting';
4
+ import postcssImport from 'postcss-import';
5
+
6
+ function colors({
7
+ style,
8
+ state,
9
+ psudoClass,
10
+ className,
11
+ visibleWrapperClass,
12
+ otherParameters,
13
+ }) {
14
+ let selector = '&';
15
+ if (psudoClass != null) {
16
+ selector += `:${psudoClass}`;
17
+ }
18
+ if (className) {
19
+ selector = `${selector}.${className}`;
20
+ }
21
+ if (visibleWrapperClass) {
22
+ selector = `${selector} ${visibleWrapperClass}`;
23
+ }
24
+ if (state === 'hover') {
25
+ return {
26
+ [selector]: {
27
+ 'border-color': `color-mix(in srgb, var(--${style}-hover-border-color) calc(var(--obc-can-hover) * 100%), var(--base-border-color))`,
28
+ 'background-color': `color-mix(in srgb, var(--${style}-hover-background-color) calc(var(--obc-can-hover) * 100%), var(--base-background-color))`,
29
+ ...otherParameters,
30
+ },
31
+ };
32
+ } else {
33
+ let extraParameters = {};
34
+ if (['enabled', 'activated'].includes(state)) {
35
+ extraParameters = {
36
+ '--base-border-color': `var(--${style}-${state}-border-color)`,
37
+ '--base-background-color': `var(--${style}-${state}-background-color)`,
38
+ };
39
+ }
40
+
41
+ return {
42
+ [selector]: {
43
+ 'border-color': `var(--${style}-${state}-border-color)`,
44
+ 'background-color': `var(--${style}-${state}-background-color)`,
45
+ ...otherParameters,
46
+ ...extraParameters,
47
+ },
48
+ };
49
+ }
50
+ }
51
+
52
+ function parseParams(params) {
53
+ const paramsArray = params.split(' ');
54
+ const paramsObject = {};
55
+ paramsArray.forEach((param) => {
56
+ const [key, value] = param.split('=');
57
+ paramsObject[key] = value || true;
58
+ });
59
+ if (!paramsObject.style) {
60
+ throw new Error('style is required');
61
+ }
62
+ return {
63
+ style: paramsObject.style,
64
+ visibleWrapperClass: paramsObject.visibleWrapperClass,
65
+ noClick: paramsObject.noClick,
66
+ };
67
+ }
68
+
69
+ const styleMixin = (data) => {
70
+ const params = parseParams(data.params);
71
+
72
+ if (params.noClick) {
73
+ return colors({
74
+ ...params,
75
+ style: params.style,
76
+ state: 'enabled',
77
+ otherParameters: {
78
+ 'border-width': '1px',
79
+ 'border-style': 'solid',
80
+ },
81
+ });
82
+ }
83
+
84
+ let focusVisibleWrapper = '&:focus-visible';
85
+ if (params.visibleWrapperClass) {
86
+ focusVisibleWrapper = `${focusVisibleWrapper} ${params.visibleWrapperClass}`;
87
+ }
88
+
89
+ const isIntegration = params.style.startsWith('integration-');
90
+ let disabledColor = `var(--on-${params.style}-disabled-color)`;
91
+ if (isIntegration) {
92
+ const styleWithoutIntegration = params.style.replace('integration-', '');
93
+ disabledColor = `var(--integration-on-${styleWithoutIntegration}-disabled-color)`;
94
+ }
95
+
96
+ const out = {
97
+ '&': {
98
+ cursor: 'pointer',
99
+ },
100
+ '&:focus': {
101
+ outline: 'none',
102
+ },
103
+ ...colors({
104
+ ...params,
105
+ style: params.style,
106
+ state: 'enabled',
107
+ otherParameters: {
108
+ 'border-width': '1px',
109
+ 'border-style': 'solid',
110
+ cursor: 'pointer',
111
+ },
112
+ }),
113
+ ...colors({
114
+ ...params,
115
+ style: params.style,
116
+ state: 'activated',
117
+ className: 'activated',
118
+ }),
119
+ '@media (hover:hover)': {
120
+ ...colors({
121
+ ...params,
122
+ style: params.style,
123
+ state: 'hover',
124
+ psudoClass: 'hover',
125
+ }),
126
+ },
127
+ ...colors({
128
+ ...params,
129
+ style: params.style,
130
+ state: 'pressed',
131
+ psudoClass: 'active',
132
+ }),
133
+ [focusVisibleWrapper]: {
134
+ 'outline-color': 'var(--border-focus-color)',
135
+ 'outline-width': 'var(--global-size-spacing-border-weight-focusframe)',
136
+ 'outline-style': 'solid',
137
+ 'border-color': 'var(--container-global-color)',
138
+ 'z-index': '1',
139
+ },
140
+ ...colors({
141
+ ...params,
142
+ style: params.style,
143
+ state: 'disabled',
144
+ psudoClass: 'disabled',
145
+ otherParameters: {
146
+ cursor: 'not-allowed',
147
+ color: disabledColor + ' !important',
148
+ },
149
+ }),
150
+ ...colors({
151
+ ...params,
152
+ style: params.style,
153
+ state: 'disabled',
154
+ className: 'disabled',
155
+ otherParameters: {
156
+ cursor: 'not-allowed',
157
+ color: disabledColor + ' !important',
158
+ },
159
+ }),
160
+ };
161
+ if (params.visibleWrapperClass) {
162
+ out['&:disabled'] = {
163
+ cursor: 'not-allowed',
164
+ };
165
+ out['&.disabled'] = {
166
+ cursor: 'not-allowed',
167
+ };
168
+ }
169
+ return out;
170
+ };
171
+
172
+ export default (ctx) => ({
173
+ parser: ctx.parser ? 'sugarss' : false,
174
+ map: ctx.env === 'development' ? ctx.map : false,
175
+ plugins: [
176
+ postcssImport(),
177
+ postcssMixins({
178
+ mixinsDir: path.join(process.cwd(), 'src', 'mixins'),
179
+ mixins: {
180
+ style: styleMixin,
181
+ },
182
+ }),
183
+ postcssNesting(),
184
+ {
185
+ postcssPlugin: 'append-global-styles',
186
+ Once(root) {
187
+ root.prepend(`
188
+ * {
189
+ -webkit-tap-highlight-color: transparent;
190
+ }
191
+ `);
192
+ },
193
+ },
194
+ ],
195
+ });