Skip to content

Commit 1c8f49d

Browse files
committed
Merge branch 'feature/9851-ecl-ec-theme' into develop
Merge ECL EC theme feature with comprehensive style updates, new ECL icons package, and updated visual test snapshots.
2 parents ebfb56c + 80f6426 commit 1c8f49d

322 files changed

Lines changed: 3870 additions & 1371 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
continue-on-error: true
6161
strategy:
6262
matrix:
63-
package: ['test-tag-name-transformer', 'theme-bwst', 'theme-default', 'theme-kern']
63+
package: ['test-tag-name-transformer', 'theme-bwst', 'theme-default', 'theme-kern', 'theme-ecl']
6464
runs-on: ubuntu-latest
6565
steps:
6666
- name: Checkout

.github/workflows/update-snapshots.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ jobs:
3838
- name: theme-kern
3939
path: packages/themes/kern
4040
type: e2e
41+
- name: theme-ecl
42+
path: packages/themes/ecl
43+
type: e2e
4144
steps:
4245
- name: Checkout branch
4346
uses: actions/checkout@v6

.github/workflows/visual-tests-base.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
run: pnpm --filter @public-ui/sample-react^... build
3434

3535
- name: Generate base snapshots
36-
run: pnpm --filter=@public-ui/${{ matrix.package }} test-update
36+
run: pnpm --filter=@public-ui/${{ matrix.package }} test:update:e2e
3737

3838
- name: Store base snapshots
3939
run: |

packages/adapters/hydrate/test/__snapshots__/components.spec.js.mocha-snapshot

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,6 @@ exports["Component hydration snapshots/renders kol-card with renderToString(0)"]
3434

3535
exports["Component hydration snapshots/renders kol-card with streamToString(0)"] = "<kol-card _label=\"Test kol-card\" s-mode=\"default\" class=\"sc-kol-card-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><kol-card-wc class=\"sc-kol-card-default hydrated\"><div aria-labelledby=\"nonce\" class=\"kol-card\" role=\"group\"><strong class=\"kol-headline kol-headline--strong kol-card__header kol-headline--single\" id=\"[id]\">Test kol-card</strong><div class=\"kol-card__content\"><slot class=\"sc-kol-card-default\"></slot></div></div></kol-card-wc></template>Test content</kol-card>";
3636

37-
exports["Component hydration snapshots/renders kol-card-wc with renderToString(0)"] = "<kol-card-wc _label=\"Test kol-card-wc\" class=\"hydrated\"><div aria-labelledby=\"nonce\" class=\"kol-card\" role=\"group\"><strong class=\"kol-headline kol-headline--strong kol-card__header kol-headline--single\" id=\"[id]\">Test kol-card-wc</strong><div class=\"kol-card__content\">Test content</div></div></kol-card-wc>";
38-
39-
exports["Component hydration snapshots/renders kol-card-wc with streamToString(0)"] = "<kol-card-wc _label=\"Test kol-card-wc\" class=\"hydrated\"><div aria-labelledby=\"nonce\" class=\"kol-card\" role=\"group\"><strong class=\"kol-headline kol-headline--strong kol-card__header kol-headline--single\" id=\"[id]\">Test kol-card-wc</strong><div class=\"kol-card__content\">Test content</div></div></kol-card-wc>";
40-
41-
exports["Component hydration snapshots/renders kol-click-button with renderToString(0)"] = "<kol-click-button _label=\"Test kol-click-button\" class=\"sc-kol-click-button-h hydrated\"><template shadowrootmode=\"open\"><button class=\"kol-click-button sc-kol-click-button\"><span class=\"kol-click-button__label sc-kol-click-button\">Test kol-click-button</span></button></template></kol-click-button>";
42-
43-
exports["Component hydration snapshots/renders kol-click-button with streamToString(0)"] = "<kol-click-button _label=\"Test kol-click-button\" class=\"sc-kol-click-button-h hydrated\"><template shadowrootmode=\"open\"><button class=\"kol-click-button sc-kol-click-button\"><span class=\"kol-click-button__label sc-kol-click-button\">Test kol-click-button</span></button></template></kol-click-button>";
44-
4537
exports["Component hydration snapshots/renders kol-combobox with renderToString(0)"] = "<kol-combobox _label=\"Test kol-combobox\" _suggestions=\"Test value\" s-mode=\"default\" class=\"sc-kol-combobox-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div class=\"kol-form-field kol-combobox sc-kol-combobox-default\"><label class=\"kol-form-field__label sc-kol-combobox-default\" id=\"[id]\" htmlfor=\"[id]\"><span class=\"kol-span kol-form-field__label-text sc-kol-combobox-default\"><span class=\"kol-span__container sc-kol-combobox-default\"><span class=\"kol-span__label sc-kol-combobox-default\">Test kol-combobox</span><span aria-hidden=\"true\" class=\"kol-span__label sc-kol-combobox-default\" hidden><slot name=\"expert\" class=\"sc-kol-combobox-default\"></slot></span></span></span></label><div class=\"kol-form-field__input sc-kol-combobox-default\"><div class=\"kol-input-container sc-kol-combobox-default\"><div class=\"kol-input-container__container sc-kol-combobox-default\"><div class=\"kol-combobox__group sc-kol-combobox-default\"><input class=\"kol-input kol-combobox__input sc-kol-combobox-default\" type=\"text\" title=\"\" autocapitalize=\"off\" autocorrect=\"off\" id=\"[id]\" role=\"combobox\" aria-autocomplete=\"both\" aria-controls=\"[id]\" aria-expanded=\"false\" aria-labelledby=\"[id]\" value=\"\"> <button type=\"button\" tabindex=\"-1\" class=\"kol-combobox-toggle sc-kol-combobox-default\"><i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-down sc-kol-combobox-default\" role=\"presentation\"></i></button></div><ul role=\"listbox\" class=\"kol-custom-suggestions-options-group sc-kol-combobox-default\" hidden></ul></div></div></div></div></template>Test content</kol-combobox>";
4638

4739
exports["Component hydration snapshots/renders kol-combobox with streamToString(0)"] = "<kol-combobox _label=\"Test kol-combobox\" _suggestions=\"Test value\" s-mode=\"default\" class=\"sc-kol-combobox-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div class=\"kol-form-field kol-combobox sc-kol-combobox-default\"><label class=\"kol-form-field__label sc-kol-combobox-default\" id=\"[id]\" htmlfor=\"[id]\"><span class=\"kol-span kol-form-field__label-text sc-kol-combobox-default\"><span class=\"kol-span__container sc-kol-combobox-default\"><span class=\"kol-span__label sc-kol-combobox-default\">Test kol-combobox</span><span aria-hidden=\"true\" class=\"kol-span__label sc-kol-combobox-default\" hidden><slot name=\"expert\" class=\"sc-kol-combobox-default\"></slot></span></span></span></label><div class=\"kol-form-field__input sc-kol-combobox-default\"><div class=\"kol-input-container sc-kol-combobox-default\"><div class=\"kol-input-container__container sc-kol-combobox-default\"><div class=\"kol-combobox__group sc-kol-combobox-default\"><input class=\"kol-input kol-combobox__input sc-kol-combobox-default\" type=\"text\" title=\"\" autocapitalize=\"off\" autocorrect=\"off\" id=\"[id]\" role=\"combobox\" aria-autocomplete=\"both\" aria-controls=\"[id]\" aria-expanded=\"false\" aria-labelledby=\"[id]\" value=\"\"> <button type=\"button\" tabindex=\"-1\" class=\"kol-combobox-toggle sc-kol-combobox-default\"><i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-down sc-kol-combobox-default\" role=\"presentation\"></i></button></div><ul role=\"listbox\" class=\"kol-custom-suggestions-options-group sc-kol-combobox-default\" hidden></ul></div></div></div></div></template>Test content</kol-combobox>";

packages/components/src/components/@shared/_table-settings.mixin.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
@mixin kol-table-settings-styles {
44
.kol-table-settings {
5-
background: #fff;
65
position: absolute;
76
top: 0;
87
right: 0;

packages/components/src/components/input-checkbox/style.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
@use '../@shared/field-control.mixin' as *;
33
@use '../@shared/form-field.mixin' as *;
44
@use '../@shared/mixins' as *;
5+
@use '../@shared/alert.mixin' as *;
56
@use '../@shared/icon.mixin' as *;
67
@use '../host-display-block' as *;
78
@use '../tooltip/style' as *;
89

910
@layer kol-component {
11+
@include kol-alert;
1012
@include kol-form-field;
1113
@include kol-field-control;
1214
@include kol-icon-styles();

packages/ecl-icons/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
font/
2+
node_modules/
3+
svg-fixed/

packages/ecl-icons/AGENTS.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Agent Instructions
2+
3+
This package contains the icon font for [KoliBri web components](https://public-ui.github.io). In KoliBri we avoid slots to ensure component accessibility, therefore we primarily support font icons. This package converts SVG files to web fonts using [svgtofont](https://wangchujiang.com/svgtofont/).
4+
5+
Use `pnpm --filter @public-ui/icons build` to build the icon font or `pnpm start` to preview the icons locally.
6+
7+
> 🧹 **Formatting**: Follow the repo-wide "Format-first rule" in `/AGENTS.md`. Run `pnpm format` or `pnpm --filter @public-ui/icons format` before committing—no extra flags are needed.
8+
9+
## Package Structure
10+
11+
- `svg/` – Source SVG files for icons. Each SVG file becomes an icon in the font.
12+
- `font/` – Generated web font files and CSS (created by build process, not committed).
13+
- `index.html` – Preview page for all icons (useful during development).
14+
- `package.json` – Package configuration including svgtofont settings.
15+
16+
## Configuration
17+
18+
The icon font is configured in `package.json`:
19+
20+
```json
21+
{
22+
"svgtofont": {
23+
"fontName": "kolicons",
24+
"classNamePrefix": "kol-icon",
25+
"css": {
26+
"fileName": "style"
27+
}
28+
}
29+
}
30+
```
31+
32+
**Important settings:**
33+
34+
- `fontName: "kolicons"` – The generated font family name
35+
- `classNamePrefix: "kol-icon"` – Prefix for all icon CSS classes (e.g., `.kol-icon-chevron-left`)
36+
- `css.fileName: "style"` – Name of the generated CSS file
37+
38+
> ⚠️ Do not change these settings unless you understand the impact on all KoliBri components that depend on the icon font.
39+
40+
## Development Workflow
41+
42+
### Building the icon font
43+
44+
Build the font from SVG sources:
45+
46+
```bash
47+
# From monorepo root
48+
pnpm --filter @public-ui/icons build
49+
50+
# Or from this directory
51+
pnpm build
52+
```
53+
54+
The build process:
55+
56+
1. Reads all SVG files from `svg/` directory
57+
2. Generates web font in multiple formats (TTF, WOFF, WOFF2, EOT, SVG)
58+
3. Creates CSS files with icon class definitions
59+
4. Outputs everything to `font/` directory
60+
61+
### Previewing icons
62+
63+
Start a local server to preview all icons:
64+
65+
```bash
66+
# From monorepo root
67+
pnpm --filter @public-ui/icons start
68+
69+
# Or from this directory
70+
pnpm start
71+
```
72+
73+
Then open `http://localhost:3000` in your browser to see the icon catalog.
74+
75+
### Adding new icons
76+
77+
1. Add your SVG file to the `svg/` directory
78+
2. Name the file descriptively (e.g., `arrow-left.svg`, `user-profile.svg`)
79+
3. Ensure the SVG meets the requirements (see below)
80+
4. Run `pnpm build` to regenerate the font
81+
5. The icon will be available as `.kol-icon-{filename}` (e.g., `.kol-icon-chevron-left`)
82+
83+
### SVG Requirements
84+
85+
For optimal results, SVG files should:
86+
87+
- **Single color**: Use black (`#000000`) or no color (stroke/fill will be set via CSS)
88+
- **ViewBox**: Must have a `viewBox` attribute (typically `0 0 24 24`)
89+
- **Simple paths**: Avoid complex features like gradients, patterns, or filters
90+
- **Optimized**: Remove unnecessary metadata, comments, and whitespace
91+
- **Consistent size**: All icons should use the same viewBox dimensions
92+
93+
**Example of a good SVG:**
94+
95+
```xml
96+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
97+
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
98+
</svg>
99+
```
100+
101+
### Testing in KoliBri Components
102+
103+
After building the font, test it with KoliBri components:
104+
105+
```tsx
106+
// In a sample app
107+
<kol-button _label="Home" _icon="home" />
108+
<kol-icon _icon="user" />
109+
```
110+
111+
## Coding Rules
112+
113+
### File Naming Conventions
114+
115+
- Use **kebab-case** for SVG filenames (e.g., `arrow-left.svg`, not `ArrowLeft.svg`)
116+
- Use descriptive names that match the icon's purpose
117+
- Avoid special characters and spaces in filenames
118+
- Keep names concise but clear
119+
120+
### SVG Best Practices
121+
122+
- **Accessibility**: Icon names should be semantic (e.g., `close` not `x`, `menu` not `hamburger`)
123+
- **Consistency**: Maintain visual consistency across all icons (same stroke width, similar style)
124+
- **Optimization**: Run SVG files through an optimizer like SVGO before adding them
125+
- **No embedded text**: Use paths only, not text elements
126+
127+
### Icon Versioning
128+
129+
When modifying existing icons:
130+
131+
- Consider the visual breaking change impact on consumers
132+
- Document significant visual changes in commit messages
133+
- Major visual changes should be discussed with the team first
134+
135+
## Build Artifacts
136+
137+
The `font/` directory is generated during build and contains:
138+
139+
- `kolicons.ttf` – TrueType font
140+
- `kolicons.woff` – Web Open Font Format (legacy)
141+
- `kolicons.woff2` – Web Open Font Format 2 (modern browsers)
142+
- `kolicons.eot` – Embedded OpenType (IE11 support)
143+
- `kolicons.svg` – SVG font (legacy fallback)
144+
- `style.css` – CSS with icon classes and font-face declarations
145+
- `index.html` – Preview page with all icons
146+
147+
**Note**: The `font/` directory is not committed to version control (it's in `.gitignore`). It's generated during build and included in the published npm package.
148+
149+
## Usage in Projects
150+
151+
After publishing, projects can use the icons:
152+
153+
```html
154+
<!-- Include the stylesheet -->
155+
<link rel="stylesheet" href="node_modules/@public-ui/icons/font/style.css" />
156+
157+
<!-- Use icons -->
158+
<i class="kol-icon-kolibri"></i>
159+
```
160+
161+
Or import in JavaScript/TypeScript:
162+
163+
```typescript
164+
import '@public-ui/icons/font/style.css';
165+
```
166+
167+
## Troubleshooting
168+
169+
### Build fails with "No SVG files found"
170+
171+
- Ensure SVG files are in the `svg/` directory
172+
- Check that files have `.svg` extension
173+
174+
### Icons display as squares
175+
176+
- The font CSS is not loaded
177+
- Check the stylesheet path in your HTML
178+
- Verify the icon class name matches an existing icon
179+
180+
### Icons look distorted
181+
182+
- SVG viewBox might be incorrect
183+
- Try standardizing all SVGs to `viewBox="0 0 24 24"`
184+
- Ensure paths are properly closed
185+
186+
### New icon doesn't appear
187+
188+
- Rebuild the font: `pnpm build`
189+
- Clear browser cache
190+
- Verify the SVG filename is valid (no special characters)
191+
192+
## Related Documentation
193+
194+
- Main KoliBri docs: [public-ui.github.io](https://public-ui.github.io)
195+
- Icon component: [public-ui.github.io/docs/components/icon](https://public-ui.github.io/docs/components/icon)
196+
- svgtofont library: [wangchujiang.com/svgtofont](https://wangchujiang.com/svgtofont/)
197+
- Monorepo agents guide: [/AGENTS.md](../../../AGENTS.md)
198+
199+
## Feedback
200+
201+
For questions, issues, or feature requests, please [open an issue on GitHub](https://github.com/public-ui/kolibri/issues).
202+
203+
## License
204+
205+
This project is licensed under the **EUPL-1.2** license. See [LICENSE](LICENSE) for details.

0 commit comments

Comments
 (0)