@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.
- package/.storybook/ComponentPreview.tsx +26 -0
- package/.storybook/PreviewTemplate.tsx +99 -0
- package/.storybook/action-handler.ts +81 -0
- package/.storybook/channels.ts +44 -0
- package/.storybook/main.ts +313 -0
- package/.storybook/manager.ts +71 -0
- package/.storybook/openbridgeTheme.ts +197 -0
- package/.storybook/preview-head.html +15 -0
- package/.storybook/preview.tsx +129 -0
- package/.storybook/vitest.setup.ts +23 -0
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +7 -1
- package/dist/components/icon-button/icon-button.d.ts +4 -0
- package/dist/components/icon-button/icon-button.d.ts.map +1 -1
- package/dist/components/icon-button/icon-button.js.map +1 -1
- package/eslint.config.mjs +589 -0
- package/fix-imports.mjs +185 -0
- package/fix-js-extensions.mjs +44 -0
- package/lit-localize.json +15 -0
- package/new-component.ts +148 -0
- package/package.json +55 -3
- package/postcss.config.mjs +195 -0
- package/script/check-css-mixins.ts +191 -0
- package/script/check-css-variables.ts +280 -0
- package/script/convert-icons.ts +202 -0
- package/script/convert-vessel-svg-to-ts.ts +110 -0
- package/script/docgen/README.md +95 -0
- package/script/docgen/docs-gen.ts +225 -0
- package/script/docgen/prompt-system.txt +187 -0
- package/script/download-alert-icons.ts +193 -0
- package/script/download-icons.ts +314 -0
- package/script/figmavariables.json +139 -0
- package/script/generate-bundle-entry.ts +77 -0
- package/script/prepare-full-bundle.ts +105 -0
- package/script/sort-custom-element-manifest.ts +67 -0
- package/src/components/icon-button/icon-button.ts +4 -0
- package/vite.config.ts +107 -0
- package/vitest.browser.config.ts +14 -0
- package/vitest.config.ts +51 -0
- package/xliff/es-419.xlf +111 -0
- package/xliff/fi-FI.xlf +139 -0
- package/dist/NotoSans.ttf +0 -0
- package/dist/oicl.svg +0 -4
package/fix-imports.mjs
ADDED
|
@@ -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
|
+
}
|
package/new-component.ts
ADDED
|
@@ -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.
|
|
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
|
-
"
|
|
99
|
-
"
|
|
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
|
+
});
|