Skip to content

Commit f5cb18a

Browse files
authored
Merge branch 'develop' into feature/user-story-fur-issue-8060-schreiben
2 parents fc8dbea + 7616bed commit f5cb18a

File tree

13 files changed

+189
-104
lines changed

13 files changed

+189
-104
lines changed

packages/components/src/functional-components/Collapsible/Collapsible.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { h } from '@stencil/core';
21
import type { FunctionalComponent as FC } from '@stencil/core';
2+
import { h } from '@stencil/core';
33
import type { JSXBase } from '@stencil/core/internal';
44
import clsx from 'clsx';
55
import { KolButtonWcTag } from '../../core/component-names';
6-
import type { HeadingLevel, IconsPropType } from '../../schema';
6+
import type { EventValueOrEventCallback, HeadingLevel, IconsPropType, StencilUnknown } from '../../schema';
77
import KolHeadingFc from '../Heading';
88

99
type ClassType =
@@ -12,12 +12,13 @@ type ClassType =
1212
[className: string]: boolean;
1313
};
1414

15-
export type CollapsibleProps = Omit<JSXBase.HTMLAttributes<HTMLElement>, 'id'> & {
15+
export type CollapsibleProps = Omit<JSXBase.HTMLAttributes<HTMLElement>, 'id' | 'onClick'> & {
1616
id: string;
1717
open?: boolean;
1818
disabled?: boolean;
1919
level?: HeadingLevel;
2020
label: string;
21+
onClick?: EventValueOrEventCallback<MouseEvent, StencilUnknown>;
2122

2223
HeadingProps?: {
2324
ref?: ((elm?: HTMLElement | undefined) => void) | undefined;

packages/components/src/functional-components/inputs/_types/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
export type DefaultInputProps<T> = Omit<T, 'title' | 'autoCapitalize' | 'autoCorrect' | 'spellcheck'> & {
1+
export type DefaultInputProps<T> = Omit<
2+
{
3+
[K in keyof T as K extends `aria${string}` ? never : K]: T[K]; // `aria${string}` is defined in the Stencil HTML types and colliding with our props, hence we remove it.
4+
},
5+
'title' | 'autoCapitalize' | 'autoCorrect' | 'spellcheck'
6+
> & {
27
id: string;
38
ariaDescribedBy?: string[];
49
hideLabel?: boolean;

packages/components/src/global/script.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,29 @@ import { getThemeDetails, setThemeStyle } from 'adopted-style-sheets';
33
import { Log } from '../schema';
44
import { setMode } from '@stencil/core';
55

6-
setMode((elm) => {
7-
try {
8-
if (elm.shadowRoot instanceof ShadowRoot) {
9-
setThemeStyle(elm, getThemeDetails(elm));
6+
export default () => {
7+
setMode((elm) => {
8+
try {
9+
if (elm.shadowRoot instanceof ShadowRoot) {
10+
setThemeStyle(elm, getThemeDetails(elm));
11+
}
12+
} catch (error) {
13+
/**
14+
* Try is needed for SSR.
15+
* - no HTMLElement is available
16+
* - no ShadowRoot is available
17+
*/
1018
}
11-
} catch (error) {
12-
/**
13-
* Try is needed for SSR.
14-
* - no HTMLElement is available
15-
* - no ShadowRoot is available
16-
*/
17-
}
18-
return 'default';
19-
});
20-
21-
import('./devtools')
22-
.then((devTools) => {
23-
if (typeof devTools === 'object' && devTools !== null && typeof devTools.initialize === 'function') {
24-
devTools.initialize();
25-
}
26-
})
27-
.catch((error) => {
28-
Log.error(error);
19+
return 'default';
2920
});
21+
22+
import('./devtools')
23+
.then((devTools) => {
24+
if (typeof devTools === 'object' && devTools !== null && typeof devTools.initialize === 'function') {
25+
devTools.initialize();
26+
}
27+
})
28+
.catch((error) => {
29+
Log.error(error);
30+
});
31+
};

packages/components/src/styles/_global.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@use '../components/a11y' as *;
22
@use '../components/preset' as *;
3+
@use '../components/@shared/mixins' as *;
34

45
@layer kol-global {
56
:host {

packages/samples/react/src/components/Sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const Sidebar: FC<Props> = ({ version, theme, routes, routeList, sample,
5353
const formatSampleAsLabel = () => sample.replace(/\//g, ' ');
5454

5555
const handleThemeSelectChange = (_event: Event, value: unknown) => {
56-
onThemeChange((value as [string])[0]);
56+
onThemeChange(value as string);
5757
};
5858

5959
const handlePreviousClick = () => {

packages/tools/kolibri-cli/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
"restart": "pnpm reset && pnpm start",
3131
"unused": "knip",
3232
"watch": "nodemon --ignore package.json src/index.ts migrate --ignore-uncommitted-changes --test-tasks test",
33-
"test": "pnpm test:unit",
34-
"test:unit": "TS_NODE_PROJECT=tsconfig.test.json mocha --require ts-node/register test/**/*.ts"
33+
"test": "pnpm test:unit",
34+
"test:unit": "TS_NODE_PROJECT=tsconfig.test.json mocha --require ts-node/register test/**/*.ts"
3535
},
3636
"type": "commonjs",
3737
"dependencies": {

packages/tools/kolibri-cli/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ generateScss(program);
3131
info(program);
3232
migrate(program);
3333

34-
program.parse();
34+
void program.parseAsync();

packages/tools/kolibri-cli/src/info/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ import { PackageJson } from '../types';
88
// Function to get the binary version
99
const getBinaryVersion = (command: string): string => {
1010
try {
11+
// For yarn, use a temporary directory to prevent package.json modification
12+
// Yarn with Corepack automatically adds packageManager field when executed
13+
if (command === 'yarn') {
14+
const originalCwd = process.cwd();
15+
const tmpDir = os.tmpdir();
16+
process.chdir(tmpDir);
17+
try {
18+
return execSync(`${command} --version`, { encoding: 'utf8' }).trim();
19+
} finally {
20+
process.chdir(originalCwd);
21+
}
22+
}
23+
1124
return execSync(`${command} --version`, { encoding: 'utf8' }).trim();
1225
} catch {
1326
return 'N/A';

packages/tools/kolibri-cli/src/migrate/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
MODIFIED_FILES,
2424
POST_MESSAGES,
2525
setRemoveMode,
26+
hasKoliBriTags,
2627
} from './shares/reuse';
2728
import { REMOVE_MODE, RemoveMode } from './types';
2829

@@ -91,6 +92,13 @@ Target version of @public-ui/*: ${options.overwriteTargetVersion}
9192
Source folder to migrate: ${baseDir}
9293
`);
9394

95+
if (!fs.existsSync(baseDir)) {
96+
throw logAndCreateError(`The specified source folder "${baseDir}" does not exist or is inaccessible. Please check the path and try again.`);
97+
}
98+
if (!hasKoliBriTags(baseDir)) {
99+
console.log(chalk.yellow(`No KoliBri components (web or React) found under "${baseDir}". Check the path or your task configuration.`));
100+
}
101+
94102
if (!options.ignoreGreaterVersion && semver.lt(options.overwriteTargetVersion, options.overwriteCurrentVersion)) {
95103
throw logAndCreateError(
96104
'Your current version of @public-ui/components is greater than the version of @public-ui/kolibri-cli. Please update @public-ui/kolibri-cli or force the migration with --ignore-greater-version.',
@@ -203,6 +211,10 @@ Modified files: ${MODIFIED_FILES.size}`);
203211
console.log(`- ${file}`);
204212
});
205213

214+
if (MODIFIED_FILES.size === 0) {
215+
console.log(chalk.yellow(`No files were modified. Verify the folder "${baseDir}" or check your .kolibri.config.json tasks.`));
216+
}
217+
206218
if (MODIFIED_FILES.size > 0 && options.format) {
207219
console.log(`
208220
We try to format the modified files with prettier...`);

packages/tools/kolibri-cli/src/migrate/shares/reuse.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import chalk from 'chalk';
22
import fs from 'fs';
33
import path from 'path';
44

5-
import { FileExtension, PackageJson } from '../../types';
5+
import { FileExtension, PackageJson, MARKUP_EXTENSIONS, WEB_TAG_REGEX, REACT_TAG_REGEX } from '../../types';
66
import { RemoveMode } from '../types';
77

88
/**
@@ -61,6 +61,45 @@ export function filterFilesByExt(dir: string, ext: FileExtension | FileExtension
6161
return files;
6262
}
6363

64+
/**
65+
* Checks if the specified directory contains any files with KoliBri tags.
66+
* Files are streamed in chunks to avoid loading entire files into memory.
67+
* @param {string} dir The directory to search in
68+
* @returns {boolean} True if at least one file contains KoliBri component tags (web or React)
69+
*/
70+
export function hasKoliBriTags(dir: string): boolean {
71+
const regexes = [WEB_TAG_REGEX, REACT_TAG_REGEX];
72+
const files = filterFilesByExt(dir, MARKUP_EXTENSIONS);
73+
74+
for (const file of files) {
75+
let fd: number | undefined;
76+
try {
77+
fd = fs.openSync(file, 'r');
78+
const buffer = Buffer.alloc(65536);
79+
let bytesRead: number;
80+
let content = '';
81+
while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null)) > 0) {
82+
content += buffer.toString('utf8', 0, bytesRead);
83+
if (regexes.some((regex) => regex.test(content))) {
84+
fs.closeSync(fd);
85+
return true;
86+
}
87+
if (content.length > 1024) {
88+
content = content.slice(-1024);
89+
}
90+
}
91+
} catch (err) {
92+
console.error(`Error reading file ${file}, skipping file due to read error:`, err);
93+
} finally {
94+
if (fd !== undefined) {
95+
fs.closeSync(fd);
96+
}
97+
}
98+
}
99+
100+
return false;
101+
}
102+
64103
/**
65104
* This function is used to get the version of the package.json as string.
66105
* @param {string} offsetPath The offset path to the package.json

0 commit comments

Comments
 (0)