@krrli/cm-designsystem 1.1.0 → 1.19.8

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 (174) hide show
  1. package/README.md +422 -2
  2. package/dist/components/avatar/Avatar.d.ts +71 -0
  3. package/dist/components/avatar/Avatar.js +63 -0
  4. package/dist/components/branding/BrandingGallery.d.ts +1 -0
  5. package/dist/components/branding/BrandingGallery.js +139 -0
  6. package/dist/components/button/Button.d.ts +54 -0
  7. package/dist/components/button/Button.js +56 -0
  8. package/dist/components/button/Button.test.d.ts +1 -0
  9. package/dist/components/button/Button.test.js +30 -0
  10. package/dist/components/color/ColorDoc.d.ts +4 -0
  11. package/dist/components/color/ColorDoc.js +10 -0
  12. package/dist/components/file-upload/FileUpload.d.ts +83 -0
  13. package/dist/components/file-upload/FileUpload.js +70 -0
  14. package/dist/components/form/Form.d.ts +54 -0
  15. package/dist/components/form/Form.js +38 -0
  16. package/dist/components/icon-button/IconButton.d.ts +50 -0
  17. package/dist/components/icon-button/IconButton.js +22 -0
  18. package/dist/components/icon-button/IconButton.test.d.ts +1 -0
  19. package/dist/components/icon-button/IconButton.test.js +22 -0
  20. package/dist/components/icons/IconBase.d.ts +5 -0
  21. package/dist/components/icons/IconBase.js +9 -0
  22. package/dist/components/icons/generated/ArrowDown.d.ts +3 -0
  23. package/dist/components/icons/generated/ArrowDown.js +4 -0
  24. package/dist/components/icons/generated/ArrowLeft.d.ts +3 -0
  25. package/dist/components/icons/generated/ArrowLeft.js +4 -0
  26. package/dist/components/icons/generated/ArrowRight.d.ts +3 -0
  27. package/dist/components/icons/generated/ArrowRight.js +4 -0
  28. package/dist/components/icons/generated/ArrowUp.d.ts +3 -0
  29. package/dist/components/icons/generated/ArrowUp.js +4 -0
  30. package/dist/components/icons/generated/Calendar.d.ts +3 -0
  31. package/dist/components/icons/generated/Calendar.js +4 -0
  32. package/dist/components/icons/generated/Cancel.d.ts +3 -0
  33. package/dist/components/icons/generated/Cancel.js +4 -0
  34. package/dist/components/icons/generated/Checkmark.d.ts +3 -0
  35. package/dist/components/icons/generated/Checkmark.js +4 -0
  36. package/dist/components/icons/generated/Edit.d.ts +3 -0
  37. package/dist/components/icons/generated/Edit.js +4 -0
  38. package/dist/components/icons/generated/Eye.d.ts +3 -0
  39. package/dist/components/icons/generated/Eye.js +4 -0
  40. package/dist/components/icons/generated/Fullscreen.d.ts +3 -0
  41. package/dist/components/icons/generated/Fullscreen.js +4 -0
  42. package/dist/components/icons/generated/HeartFilled.d.ts +3 -0
  43. package/dist/components/icons/generated/HeartFilled.js +4 -0
  44. package/dist/components/icons/generated/HeartOutline.d.ts +3 -0
  45. package/dist/components/icons/generated/HeartOutline.js +4 -0
  46. package/dist/components/icons/generated/Location.d.ts +3 -0
  47. package/dist/components/icons/generated/Location.js +4 -0
  48. package/dist/components/icons/generated/LogOut.d.ts +3 -0
  49. package/dist/components/icons/generated/LogOut.js +4 -0
  50. package/dist/components/icons/generated/Mumble.d.ts +3 -0
  51. package/dist/components/icons/generated/Mumble.js +4 -0
  52. package/dist/components/icons/generated/Profile.d.ts +3 -0
  53. package/dist/components/icons/generated/Profile.js +4 -0
  54. package/dist/components/icons/generated/ReplyFilled.d.ts +3 -0
  55. package/dist/components/icons/generated/ReplyFilled.js +4 -0
  56. package/dist/components/icons/generated/ReplyOutline.d.ts +3 -0
  57. package/dist/components/icons/generated/ReplyOutline.js +4 -0
  58. package/dist/components/icons/generated/Repost.d.ts +3 -0
  59. package/dist/components/icons/generated/Repost.js +4 -0
  60. package/dist/components/icons/generated/Send.d.ts +3 -0
  61. package/dist/components/icons/generated/Send.js +4 -0
  62. package/dist/components/icons/generated/Settings.d.ts +3 -0
  63. package/dist/components/icons/generated/Settings.js +4 -0
  64. package/dist/components/icons/generated/Share.d.ts +3 -0
  65. package/dist/components/icons/generated/Share.js +4 -0
  66. package/dist/components/icons/generated/Time.d.ts +3 -0
  67. package/dist/components/icons/generated/Time.js +4 -0
  68. package/dist/components/icons/generated/Upload.d.ts +3 -0
  69. package/dist/components/icons/generated/Upload.js +4 -0
  70. package/dist/components/icons/generated/index.d.ts +24 -0
  71. package/dist/components/icons/generated/index.js +24 -0
  72. package/dist/components/index.d.ts +25 -0
  73. package/dist/components/index.js +25 -0
  74. package/dist/components/input/Input.d.ts +61 -0
  75. package/dist/components/input/Input.js +47 -0
  76. package/dist/components/like-toggle/LikeToggle.d.ts +97 -0
  77. package/dist/components/like-toggle/LikeToggle.js +185 -0
  78. package/dist/components/like-toggle/LikeToggle.test.d.ts +1 -0
  79. package/dist/components/like-toggle/LikeToggle.test.js +35 -0
  80. package/dist/components/modal/Modal.d.ts +75 -0
  81. package/dist/components/modal/Modal.js +63 -0
  82. package/dist/components/modal/Modal.test.d.ts +1 -0
  83. package/dist/components/modal/Modal.test.js +24 -0
  84. package/dist/components/navi-button/NaviButton.d.ts +26 -0
  85. package/dist/components/navi-button/NaviButton.js +29 -0
  86. package/dist/components/navi-button/NaviButton.test.d.ts +1 -0
  87. package/dist/components/navi-button/NaviButton.test.js +22 -0
  88. package/dist/components/navi-user-button/NaviUserButton.d.ts +26 -0
  89. package/dist/components/navi-user-button/NaviUserButton.js +29 -0
  90. package/dist/components/round-button/RoundButton.d.ts +25 -0
  91. package/dist/components/round-button/RoundButton.js +28 -0
  92. package/dist/components/round-button/RoundButton.test.d.ts +1 -0
  93. package/dist/components/round-button/RoundButton.test.js +21 -0
  94. package/dist/components/tabs/TabItem.d.ts +11 -0
  95. package/dist/components/tabs/TabItem.js +13 -0
  96. package/dist/components/tabs/Tabs.d.ts +67 -0
  97. package/dist/components/tabs/Tabs.js +67 -0
  98. package/dist/components/tabs/Tabs.test.d.ts +1 -0
  99. package/dist/components/tabs/Tabs.test.js +61 -0
  100. package/dist/components/text-link/TextLink.d.ts +9 -0
  101. package/dist/components/text-link/TextLink.js +15 -0
  102. package/dist/components/text-link/TextLink.test.d.ts +1 -0
  103. package/dist/components/text-link/TextLink.test.js +14 -0
  104. package/dist/components/textarea/Textarea.d.ts +48 -0
  105. package/dist/components/textarea/Textarea.js +46 -0
  106. package/dist/components/timed-button/TimedButton.d.ts +56 -0
  107. package/dist/components/timed-button/TimedButton.js +106 -0
  108. package/dist/components/timed-button/TimedButton.test.d.ts +1 -0
  109. package/dist/components/timed-button/TimedButton.test.js +35 -0
  110. package/dist/components/toggle/Toggle.d.ts +62 -0
  111. package/dist/components/toggle/Toggle.js +67 -0
  112. package/dist/components/toggle/Toggle.test.d.ts +1 -0
  113. package/dist/components/toggle/Toggle.test.js +93 -0
  114. package/dist/components/typography/Heading.d.ts +17 -0
  115. package/dist/components/typography/Heading.js +11 -0
  116. package/dist/components/typography/Label.d.ts +15 -0
  117. package/dist/components/typography/Label.js +7 -0
  118. package/dist/components/typography/Paragraph.d.ts +15 -0
  119. package/dist/components/typography/Paragraph.js +7 -0
  120. package/dist/components/typography/Placeholder.d.ts +13 -0
  121. package/dist/components/typography/Placeholder.js +7 -0
  122. package/dist/components/typography/ValidationMessage.d.ts +15 -0
  123. package/dist/components/typography/ValidationMessage.js +9 -0
  124. package/dist/components/typography/styles.d.ts +74 -0
  125. package/dist/components/typography/styles.js +52 -0
  126. package/dist/favicon.svg +18 -0
  127. package/dist/index.d.ts +1 -0
  128. package/dist/index.es.js +7550 -0
  129. package/dist/index.js +2 -0
  130. package/dist/logo-inline-gradient.svg +43 -0
  131. package/dist/setupTests.d.ts +1 -0
  132. package/dist/setupTests.js +7 -0
  133. package/package.json +78 -33
  134. package/.github/CODEOWNERS +0 -7
  135. package/.github/semantic.yml +0 -24
  136. package/.github/workflows/publish-npm.yml +0 -29
  137. package/.github/workflows/storybook.yml +0 -44
  138. package/.releaserc.json +0 -9
  139. package/.storybook/main.ts +0 -19
  140. package/.storybook/preview.ts +0 -21
  141. package/.storybook/vitest.setup.ts +0 -7
  142. package/src/index.ts +0 -4
  143. package/stories/Button.stories.ts +0 -54
  144. package/stories/Button.tsx +0 -37
  145. package/stories/Button2.stories.ts +0 -54
  146. package/stories/Button2.tsx +0 -41
  147. package/stories/Configure.mdx +0 -364
  148. package/stories/Header.stories.ts +0 -34
  149. package/stories/Header.tsx +0 -56
  150. package/stories/Page.stories.ts +0 -33
  151. package/stories/Page.tsx +0 -73
  152. package/stories/assets/accessibility.png +0 -0
  153. package/stories/assets/accessibility.svg +0 -1
  154. package/stories/assets/addon-library.png +0 -0
  155. package/stories/assets/assets.png +0 -0
  156. package/stories/assets/avif-test-image.avif +0 -0
  157. package/stories/assets/context.png +0 -0
  158. package/stories/assets/discord.svg +0 -1
  159. package/stories/assets/docs.png +0 -0
  160. package/stories/assets/figma-plugin.png +0 -0
  161. package/stories/assets/github.svg +0 -1
  162. package/stories/assets/share.png +0 -0
  163. package/stories/assets/styling.png +0 -0
  164. package/stories/assets/testing.png +0 -0
  165. package/stories/assets/theming.png +0 -0
  166. package/stories/assets/tutorials.svg +0 -1
  167. package/stories/assets/youtube.svg +0 -1
  168. package/stories/button.css +0 -30
  169. package/stories/button2.css +0 -30
  170. package/stories/header.css +0 -32
  171. package/stories/page.css +0 -68
  172. package/tsconfig.json +0 -13
  173. package/vitest.config.ts +0 -35
  174. package/vitest.shims.d.ts +0 -1
package/README.md CHANGED
@@ -1,2 +1,422 @@
1
- # cm-designsystem
2
- Design System
1
+ # CM Design System
2
+
3
+ A modern React component library built with TypeScript, Tailwind CSS, and Storybook.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Usage in Your Project](#usage-in-your-project)
8
+ - [Technical Stack](#technical-stack)
9
+ - [Development](#development)
10
+ - [Quick Start Development](#quick-start-development)
11
+ - [Quality Checks](#quality-checks)
12
+ - [Code Style](#code-style)
13
+ - [TypeScript Guidelines](#typescript-guidelines)
14
+ - [Project Structure](#project-structure)
15
+ - [Icon Generation](#icon-generation)
16
+ - [Visual Testing](#visual-testing)
17
+ - [Contributing](#contributing)
18
+ - [Continuous Integration](#continuous-integration)
19
+ - [EditorConfig & VS Code Settings](#editorconfig--vs-code-settings)
20
+
21
+ ## Usage in Your Project
22
+
23
+ To use the components and styles in your project:
24
+
25
+ 1. Install the package:
26
+
27
+ ```bash
28
+ npm i @krrli/cm-designsystem
29
+ ```
30
+
31
+ 2. Import the bundled CSS in your app entry (e.g., `main.tsx` or `App.tsx`):
32
+
33
+ ```js
34
+ import "cm-designsystem/dist/cm-designsystem.css";
35
+ ```
36
+
37
+ 3. Import and use components as needed:
38
+
39
+ ```js
40
+ import { Button } from "cm-designsystem";
41
+
42
+ function App() {
43
+ return (
44
+ <Button label="Click me" intent="primary" size="md" onClick={() => {}} />
45
+ );
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Technical Stack
52
+
53
+ - React 19 with TypeScript
54
+ - Vite for fast development and building
55
+ - Tailwind CSS v4 for styling
56
+ - Storybook for component documentation
57
+ - Vitest for unit testing
58
+ - Playwright for visual regression testing
59
+ - Radix UI Primitives for accessible component primitives
60
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react) for Fast Refresh
61
+
62
+ ---
63
+
64
+ ## Development
65
+
66
+ ### Quick Start Development
67
+
68
+ ```bash
69
+ # Install dependencies
70
+ npm install
71
+
72
+ # Start Storybook development server
73
+ npm run storybook
74
+ ```
75
+
76
+ Storybook will be available at [http://localhost:6006](http://localhost:6006)
77
+
78
+ 📚 View the deployed Storybook: [https://ost-cas-fea-25-26.github.io/cm-designsystem/](https://ost-cas-fea-25-26.github.io/cm-designsystem/?path=/docs/branding-assets--docs)
79
+
80
+ ### Quality Checks
81
+
82
+ Run all quality checks before committing:
83
+
84
+ ```bash
85
+ npm run preflight # Runs format, lint, type-check, test, and build
86
+ ```
87
+
88
+ Individual commands:
89
+
90
+ ```bash
91
+ # Formatting
92
+ npm run format # Auto-format all files with Prettier
93
+ npm run format:check # Check formatting without making changes
94
+
95
+ # Linting
96
+ npm run lint # Check for linting errors
97
+ npm run lint:fix # Auto-fix linting errors where possible
98
+
99
+ # Type Checking
100
+ npx tsc -b --noEmit # Run TypeScript type checking
101
+
102
+ # Testing
103
+ npm test # Run unit tests with Vitest
104
+
105
+ # Building
106
+ npm run build # Build the project
107
+ npm run build-storybook # Build Storybook for production
108
+ ```
109
+
110
+ ### Code Style
111
+
112
+ We enforce consistent code style using automated tools:
113
+
114
+ Prettier Configuration:
115
+
116
+ - Uses double quotes
117
+ - 2-space indentation
118
+ - Semicolons required
119
+ - Line width: 80 characters
120
+ - Includes Tailwind CSS class sorting plugin
121
+
122
+ ESLint Configuration:
123
+
124
+ - TypeScript ESLint rules
125
+ - React and React Hooks best practices
126
+ - JSX Accessibility (a11y) rules
127
+ - Import sorting and organization
128
+ - Storybook rules
129
+ - Prettier integration (no conflicts)
130
+
131
+ ### TypeScript Guidelines
132
+
133
+ We follow a consistent pattern for component type definitions:
134
+
135
+ Standard Component Pattern:
136
+
137
+ ```tsx
138
+ import { tv, type VariantProps } from "tailwind-variants";
139
+
140
+ // 1. Define styles with tailwind-variants
141
+ const buttonStyles = tv({
142
+ variants: {
143
+ intent: {
144
+ primary: ["bg-slate-600"],
145
+ secondary: ["bg-violet-600"],
146
+ },
147
+ size: {
148
+ md: ["pt-3", "pb-3"],
149
+ lg: ["pt-4", "pb-4"],
150
+ },
151
+ },
152
+ });
153
+
154
+ // 2. Extract variant types from styles
155
+ type ButtonVariants = VariantProps<typeof buttonStyles>;
156
+
157
+ // 3. Define specific union types for variant options
158
+ type ButtonIntent = "primary" | "secondary";
159
+ type ButtonSize = "md" | "lg";
160
+
161
+ // 4. Create component props interface extending variants
162
+ interface ButtonProps extends ButtonVariants {
163
+ label: string;
164
+ onClick: () => void;
165
+ className?: string;
166
+ }
167
+ ```
168
+
169
+ When to use `type` vs `interface`:
170
+
171
+ - `type`: For VariantProps, union types, and type aliases
172
+ - `interface`: For component props (always extends variants)
173
+ - `export`: Export interfaces for public component APIs
174
+
175
+ Best Practices:
176
+
177
+ - Always extend `VariantProps` for styled components
178
+ - Define union types for variant options to ensure type safety
179
+ - Export prop interfaces for components
180
+ - Use strict TypeScript (enabled by default)
181
+
182
+ ### Project Structure
183
+
184
+ Components and their Storybook stories are co-located in the same folder for better organization:
185
+
186
+ ```
187
+ src/components/
188
+ ├── button/
189
+ │ ├── Button.tsx # Component implementation
190
+ │ ├── Button.stories.tsx # Storybook stories
191
+ │ └── Button.test.tsx # Unit tests (if applicable)
192
+ ├── avatar/
193
+ │ ├── Avatar.tsx
194
+ │ └── Avatar.stories.tsx
195
+ └── ...
196
+ ```
197
+
198
+ Benefits of co-location:
199
+
200
+ - ✅ Related files stay together
201
+ - ✅ Easier to find and maintain stories
202
+ - ✅ Clear 1:1 relationship between components and documentation
203
+ - ✅ Stories serve as living documentation and examples
204
+
205
+ Story file naming: Always use `ComponentName.stories.tsx` format for Storybook to auto-discover them.
206
+
207
+ ---
208
+
209
+ ## Icon Generation
210
+
211
+ SVG icons are automatically converted to React components with proper accessibility support.
212
+
213
+ ### Workflow
214
+
215
+ 1. Add SVG files to `src/components/icons/svg/`
216
+ 2. Optimize SVGs (optional but recommended):
217
+ ```bash
218
+ npx svgo -f src/components/icons/svg
219
+ ```
220
+ 3. Generate React components:
221
+ ```bash
222
+ npm run icons:generate
223
+ ```
224
+
225
+ ### Configuration
226
+
227
+ Edit `svg.config.json` to customize the generation process:
228
+
229
+ ```json
230
+ {
231
+ "sourceDir": "src/components/icons/svg",
232
+ "outputDir": "src/components/icons/generated",
233
+ "baseComponentImport": {
234
+ "name": "IconBase",
235
+ "path": "../IconBase"
236
+ }
237
+ }
238
+ ```
239
+
240
+ ### Usage Example
241
+
242
+ ```tsx
243
+ import { Calendar, LogOut } from "src/components/icons/generated";
244
+
245
+ export function Example() {
246
+ return (
247
+ <div className="flex gap-2 text-slate-600">
248
+ <Calendar />
249
+ <LogOut className="text-red-600" />
250
+ </div>
251
+ );
252
+ }
253
+ ```
254
+
255
+ How it works:
256
+
257
+ - File names are converted to PascalCase (`log-out.svg` → `LogOut`)
258
+ - Fill colors are normalized to `currentColor` for theming
259
+ - All icons are wrapped in `IconBase` for accessibility
260
+ - A barrel export (`index.ts`) is generated automatically
261
+
262
+ ---
263
+
264
+ ## Visual Testing
265
+
266
+ We use Playwright for visual regression testing against Storybook. Tests run in Docker for consistent results across environments.
267
+
268
+ ### Setup
269
+
270
+ Build the Docker image (first time only):
271
+
272
+ ```bash
273
+ npm run e2e:build
274
+ ```
275
+
276
+ ### Running Tests
277
+
278
+ ```bash
279
+ npm run e2e:test # Run visual regression tests
280
+ npm run e2e:update # Update baseline snapshots
281
+ ```
282
+
283
+ ### Viewing Reports
284
+
285
+ View test reports locally:
286
+
287
+ ```bash
288
+ npx playwright show-report
289
+ ```
290
+
291
+ GitHub Artifacts:
292
+ Test reports are uploaded as CI artifacts. Download and view them with:
293
+
294
+ ```bash
295
+ npx playwright show-report <path/to/extracted-artifact>
296
+ ```
297
+
298
+ ### Configuration
299
+
300
+ - Docker: Tests run in containers for consistency across environments
301
+ - Network: Storybook accepts connections from `host.docker.internal`
302
+ - Tolerance: 1% pixel difference allowed (`maxDiffPixelRatio: 0.01`)
303
+ - Files: `playwright.config.ts` and `.storybook/main.ts`
304
+
305
+ ---
306
+
307
+ ## Contributing
308
+
309
+ ### Pull Request Process
310
+
311
+ 1. Create a feature branch:
312
+
313
+ ```bash
314
+ git checkout -b feature/initials/your-feature-name
315
+ ```
316
+
317
+ Use format: `feature/<mm or ci>/<description>`
318
+
319
+ 2. Make your changes and ensure quality:
320
+
321
+ ```bash
322
+ npm run preflight
323
+ ```
324
+
325
+ 3. Commit with conventional commits (see below)
326
+
327
+ 4. Push to your feature branch:
328
+
329
+ ```bash
330
+ git push origin feature/initials/your-feature-name
331
+ ```
332
+
333
+ 5. Create a pull request to `main`
334
+
335
+ 6. Wait for CI checks to pass
336
+
337
+ 7. Request review from team members
338
+
339
+ 8. Address feedback and merge
340
+
341
+ ### Commit Messages
342
+
343
+ We use [Conventional Commits](https://www.conventionalcommits.org/) for consistent versioning and changelog generation.
344
+
345
+ Format:
346
+
347
+ ```
348
+ <type>: <description>
349
+
350
+ [optional body]
351
+ ```
352
+
353
+ Types:
354
+
355
+ - `feat`: New feature
356
+ - `fix`: Bug fix
357
+ - `docs`: Documentation changes
358
+ - `style`: Code style/formatting (no logic change)
359
+ - `refactor`: Code refactoring (no feature/bug change)
360
+ - `test`: Adding or updating tests
361
+ - `chore`: Maintenance tasks (dependencies, config, etc.)
362
+ - `perf`: Performance improvements
363
+
364
+ Examples:
365
+
366
+ ```
367
+ feat: add new Button variant
368
+ fix: correct Typography component spacing
369
+ docs: update README with visual testing guide
370
+ chore: update dependencies
371
+ test: add tests for TextLink component
372
+ ```
373
+
374
+ ---
375
+
376
+ ## Continuous Integration
377
+
378
+ All pull requests are automatically validated through our CI pipeline.
379
+
380
+ ### Required Checks
381
+
382
+ 1. ✅ Format & Lint - Code must be properly formatted and pass linting
383
+ 2. ✅ Type Check - No TypeScript errors
384
+ 3. ✅ Tests - All unit tests must pass
385
+ 4. ✅ Build - Project must build successfully
386
+ 5. ✅ Build Storybook - Storybook must build successfully
387
+ 6. ✅ Visual Tests - Playwright visual regression tests must pass
388
+
389
+ ### Pipeline Triggers
390
+
391
+ - Pull requests to `main`
392
+ - Pushes to `main`
393
+
394
+ ### Why No Pre-commit Hooks?
395
+
396
+ We intentionally don't use pre-commit hooks (like Husky):
397
+
398
+ - ✅ Quality checks in CI can't be bypassed
399
+ - ✅ Faster local development workflow
400
+ - ✅ CI is the single source of truth
401
+
402
+ Note: You're encouraged to run `npm run preflight` locally before pushing!
403
+
404
+ ---
405
+
406
+ ## EditorConfig & VS Code Settings
407
+
408
+ This project uses a strict `.editorconfig` to ensure consistent code style across all editors and platforms. Most formatting rules (indentation, line endings, trailing whitespace, etc.) are enforced automatically if you have the [EditorConfig extension](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) installed in VS Code.
409
+
410
+ Additionally, the repository includes a `.vscode/settings.json` file to avoid conflicts between VS Code's built-in formatting and EditorConfig:
411
+
412
+ ```json
413
+ {
414
+ "editor.formatOnSave": true,
415
+ "files.trimTrailingWhitespace": false,
416
+ "files.insertFinalNewline": false,
417
+ "files.eol": "\n"
418
+ }
419
+ ```
420
+
421
+ - No further VS Code settings are required—just make sure the EditorConfig extension is enabled.
422
+ - These settings ensure that formatting is always consistent, regardless of individual developer/editor preferences.
@@ -0,0 +1,71 @@
1
+ import { type VariantProps } from "tailwind-variants";
2
+ declare const avatarStyles: import("tailwind-variants").TVReturnType<{
3
+ size: {
4
+ sm: {
5
+ avatar: string[];
6
+ };
7
+ md: {
8
+ avatar: string[];
9
+ };
10
+ lg: {
11
+ avatar: string[];
12
+ };
13
+ xl: {
14
+ avatar: string[];
15
+ };
16
+ };
17
+ }, {
18
+ base: string[];
19
+ avatar: string[];
20
+ action: string[];
21
+ }, undefined, {
22
+ size: {
23
+ sm: {
24
+ avatar: string[];
25
+ };
26
+ md: {
27
+ avatar: string[];
28
+ };
29
+ lg: {
30
+ avatar: string[];
31
+ };
32
+ xl: {
33
+ avatar: string[];
34
+ };
35
+ };
36
+ }, {
37
+ base: string[];
38
+ avatar: string[];
39
+ action: string[];
40
+ }, import("tailwind-variants").TVReturnType<{
41
+ size: {
42
+ sm: {
43
+ avatar: string[];
44
+ };
45
+ md: {
46
+ avatar: string[];
47
+ };
48
+ lg: {
49
+ avatar: string[];
50
+ };
51
+ xl: {
52
+ avatar: string[];
53
+ };
54
+ };
55
+ }, {
56
+ base: string[];
57
+ avatar: string[];
58
+ action: string[];
59
+ }, undefined, unknown, unknown, undefined>>;
60
+ type AvatarVariants = VariantProps<typeof avatarStyles>;
61
+ type AvatarSize = "sm" | "md" | "lg" | "xl";
62
+ interface AvatarProps extends AvatarVariants {
63
+ label: string;
64
+ size: AvatarSize;
65
+ src: string;
66
+ children: React.ReactNode;
67
+ onClick?: () => void;
68
+ onActionClick?: () => void;
69
+ }
70
+ export declare const Avatar: (props: AvatarProps) => import("react/jsx-runtime").JSX.Element;
71
+ export {};
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as RadixAvatar from "@radix-ui/react-avatar";
3
+ import { tv } from "tailwind-variants";
4
+ import { Edit } from "../icons/generated";
5
+ import { RoundButton } from "../round-button/RoundButton";
6
+ const avatarStyles = tv({
7
+ slots: {
8
+ base: ["relative", "inline-block"],
9
+ avatar: [
10
+ "rounded-full",
11
+ "transition",
12
+ "duration-300",
13
+ "ease-in-out",
14
+ "min-w-10",
15
+ "min-h-10",
16
+ "flex",
17
+ "items-center",
18
+ "justify-center",
19
+ ],
20
+ action: ["absolute", "bottom-2", "right-2"],
21
+ },
22
+ variants: {
23
+ size: {
24
+ sm: { avatar: ["w-10", "h-10", "hover:scale-105"] },
25
+ md: {
26
+ avatar: [
27
+ "w-16",
28
+ "h-16",
29
+ "border",
30
+ "border-solid",
31
+ "border-slate-100",
32
+ "border-6",
33
+ "hover:scale-105",
34
+ ],
35
+ },
36
+ lg: {
37
+ avatar: [
38
+ "w-24",
39
+ "h-24",
40
+ "border",
41
+ "border-solid",
42
+ "border-slate-100",
43
+ "border-6",
44
+ "hover:scale-95",
45
+ ],
46
+ },
47
+ xl: {
48
+ avatar: [
49
+ "w-40",
50
+ "h-40",
51
+ "border",
52
+ "border-solid",
53
+ "border-slate-100",
54
+ "border-6",
55
+ ],
56
+ },
57
+ },
58
+ },
59
+ });
60
+ export const Avatar = (props) => {
61
+ const { base, avatar, action } = avatarStyles(props);
62
+ return (_jsxs(RadixAvatar.Root, { onClick: props.onClick, className: base(props), children: [_jsx(RadixAvatar.Image, { src: props.src, alt: props.label, className: avatar(props) }), props.size === "xl" && props.onActionClick && (_jsx("div", { className: action(props), children: _jsx(RoundButton, { intent: "primary", ariaLabel: `Edit ${props.label}`, onClick: props.onActionClick ?? (() => { }), children: _jsx(Edit, {}) }) })), _jsx(RadixAvatar.Fallback, { children: _jsx("div", { className: avatar(props), children: props.children }) })] }));
63
+ };
@@ -0,0 +1 @@
1
+ export declare const BrandingGallery: React.FC;
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import appIconGradient from "./app-icon-gradient.svg";
3
+ import appIconWhite from "./app-icon-white.svg";
4
+ import hoverLogo from "./hover-logo.svg";
5
+ import logoInlineGradient from "./logo-inline-gradient.svg";
6
+ import logoInlineViolet from "./logo-inline-violet.svg";
7
+ import logoInlineWhite from "./logo-inline-white.svg";
8
+ import logoStackedGradient from "./logo-stacked-gradient.svg";
9
+ import logoStackedViolet from "./logo-stacked-violet.svg";
10
+ import logoStackedWhite from "./logo-stacked-white.svg";
11
+ import superzeichen from "./superzeichen.svg";
12
+ const brandingAssets = {
13
+ "App Icons": [
14
+ {
15
+ name: "App Icon Gradient",
16
+ src: appIconGradient,
17
+ width: 64,
18
+ height: 64,
19
+ filename: "app-icon-gradient.svg",
20
+ },
21
+ {
22
+ name: "App Icon White",
23
+ src: appIconWhite,
24
+ width: 64,
25
+ height: 64,
26
+ filename: "app-icon-white.svg",
27
+ },
28
+ ],
29
+ Logos: [
30
+ {
31
+ name: "Logo Inline Gradient",
32
+ src: logoInlineGradient,
33
+ width: 335,
34
+ height: 64,
35
+ filename: "logo-inline-gradient.svg",
36
+ },
37
+ {
38
+ name: "Logo Inline Violet",
39
+ src: logoInlineViolet,
40
+ width: 335,
41
+ height: 64,
42
+ filename: "logo-inline-violet.svg",
43
+ },
44
+ {
45
+ name: "Logo Inline White",
46
+ src: logoInlineWhite,
47
+ width: 335,
48
+ height: 64,
49
+ filename: "logo-inline-white.svg",
50
+ },
51
+ {
52
+ name: "Logo Stacked Gradient",
53
+ src: logoStackedGradient,
54
+ width: 210,
55
+ height: 80,
56
+ filename: "logo-stacked-gradient.svg",
57
+ },
58
+ {
59
+ name: "Logo Stacked Violet",
60
+ src: logoStackedViolet,
61
+ width: 210,
62
+ height: 80,
63
+ filename: "logo-stacked-violet.svg",
64
+ },
65
+ {
66
+ name: "Logo Stacked White",
67
+ src: logoStackedWhite,
68
+ width: 210,
69
+ height: 80,
70
+ filename: "logo-stacked-white.svg",
71
+ },
72
+ ],
73
+ "Hover Logo": [
74
+ {
75
+ name: "Hover Logo",
76
+ src: hoverLogo,
77
+ width: 64,
78
+ height: 64,
79
+ filename: "hover-logo.svg",
80
+ },
81
+ ],
82
+ Superzeichen: [
83
+ {
84
+ name: "Superzeichen",
85
+ src: superzeichen,
86
+ width: 64,
87
+ height: 64,
88
+ filename: "superzeichen.svg",
89
+ },
90
+ ],
91
+ };
92
+ export const BrandingGallery = () => (_jsx("div", { children: Object.entries(brandingAssets).map(([category, assets]) => (_jsxs("div", { style: { marginBottom: 48 }, children: [_jsx("h2", { style: {
93
+ fontSize: 20,
94
+ fontWeight: 600,
95
+ marginBottom: 24,
96
+ marginTop: 0,
97
+ }, children: category }), _jsx("div", { style: {
98
+ display: "grid",
99
+ gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))",
100
+ gap: 32,
101
+ padding: 4,
102
+ }, children: assets.map(({ name, src, width, height, filename }) => {
103
+ const isWhiteVariant = filename.includes("white") || filename.includes("hover");
104
+ return (_jsxs("div", { style: {
105
+ display: "flex",
106
+ flexDirection: "column",
107
+ alignItems: "center",
108
+ border: "1px solid #eee",
109
+ padding: 24,
110
+ borderRadius: 8,
111
+ backgroundColor: "#fafafa",
112
+ gap: 16,
113
+ }, children: [_jsx("div", { style: {
114
+ display: "flex",
115
+ alignItems: "center",
116
+ justifyContent: "center",
117
+ minHeight: 120,
118
+ width: "100%",
119
+ backgroundColor: isWhiteVariant ? "#7c3aed" : "transparent",
120
+ borderRadius: 4,
121
+ padding: isWhiteVariant ? 16 : 0,
122
+ }, children: _jsx("img", { src: src, alt: name, style: {
123
+ maxWidth: "100%",
124
+ height: "auto",
125
+ objectFit: "contain",
126
+ } }) }), _jsxs("div", { style: {
127
+ textAlign: "center",
128
+ width: "100%",
129
+ }, children: [_jsx("div", { style: { fontWeight: 600, marginBottom: 8 }, children: name }), _jsx("code", { style: {
130
+ fontSize: 11,
131
+ color: "#666",
132
+ display: "block",
133
+ marginBottom: 4,
134
+ }, children: filename }), _jsxs("code", { style: {
135
+ fontSize: 11,
136
+ color: "#666",
137
+ display: "block",
138
+ }, children: [width, " \u00D7 ", height] })] })] }, name));
139
+ }) })] }, category))) }));