@mindvalley/design-system 4.0.1 → 4.1.1

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.
@@ -0,0 +1,31 @@
1
+ export interface TypographyToken {
2
+ fontFamily: string;
3
+ fontSize: string;
4
+ lineHeight: string;
5
+ letterSpacing: string;
6
+ fontWeight?: number;
7
+ [key: string]: string | number | undefined;
8
+ }
9
+ export interface TypographySet {
10
+ [key: string]: TypographyToken;
11
+ }
12
+ export interface BreakpointsConfig {
13
+ tablet?: string;
14
+ desktop?: string;
15
+ [key: string]: string | undefined;
16
+ }
17
+ export interface TypographyPluginOptions {
18
+ casing?: 'snakeCase' | 'camelCase' | 'pascalCase' | 'kebabCase' | 'noCase';
19
+ breakpoints?: BreakpointsConfig;
20
+ prefix?: string;
21
+ brands?: string[];
22
+ }
23
+ declare const _default: {
24
+ (options: TypographyPluginOptions | undefined): {
25
+ handler: import("tailwindcss/types/config").PluginCreator;
26
+ config?: Partial<import("tailwindcss/types/config").Config>;
27
+ };
28
+ __isOptionsFunction: true;
29
+ };
30
+ export default _default;
31
+ //# sourceMappingURL=typography-gsf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typography-gsf.d.ts","sourceRoot":"","sources":["../../../src/tailwind/plugins/typography-gsf.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAC3C;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAA;CAC/B;AAeD,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAA;IAC1E,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;;;;cAzCE,CAAC;;;;AAgPJ,wBAAmD"}
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const plugin_1 = __importDefault(require("tailwindcss/plugin"));
7
+ const casing_1 = require("../../helpers/casing");
8
+ const dimens_1 = require("../../helpers/dimens");
9
+ const typography_1 = __importDefault(require("./tokens/b2b/typography"));
10
+ const typography_gsf_1 = __importDefault(require("./tokens/mindvalley/typography-gsf"));
11
+ const brandMapping = {
12
+ mindvalley: typography_gsf_1.default,
13
+ b2b: typography_1.default,
14
+ };
15
+ function typographyPlugin(options = {}) {
16
+ return ({ addUtilities, theme }) => {
17
+ const { casing = casing_1.CASINGS.kebabCase, breakpoints = {}, prefix = '', brands = ['mindvalley'], } = options;
18
+ const tabletBreakpoint = breakpoints.tablet ?? theme('screens.md', '768px');
19
+ const desktopBreakpoint = breakpoints.desktop ?? theme('screens.lg', '1024px');
20
+ const typographyClassDeclarations = {};
21
+ for (const brand of brands) {
22
+ const brandTypography = brandMapping[brand];
23
+ if (!brandTypography) {
24
+ continue;
25
+ }
26
+ const processedTypography = processTypography(brandTypography, tabletBreakpoint, desktopBreakpoint);
27
+ const casedTypography = convertObjectKeysToCasedClassNames(processedTypography, casing, prefix);
28
+ Object.assign(typographyClassDeclarations, casedTypography);
29
+ }
30
+ addUtilities(typographyClassDeclarations);
31
+ };
32
+ }
33
+ function processTypography(typography, tabletBreakpoint, desktopBreakpoint) {
34
+ const result = {};
35
+ for (const key of Object.keys(typography)) {
36
+ const isDesktop = key.endsWith('-desktop');
37
+ const isTablet = key.endsWith('-tablet');
38
+ const isMobile = key.endsWith('-mobile');
39
+ const baseTypography = typography[key];
40
+ const baseKey = isDesktop || isTablet || isMobile
41
+ ? (0, casing_1.toCamelCase)(key.replace(/-desktop$|-tablet$|-mobile$/g, ''))
42
+ : key;
43
+ if (isDesktop) {
44
+ const existing = result[baseKey] || {};
45
+ result[baseKey] = {
46
+ ...existing,
47
+ [`@media (min-width: ${desktopBreakpoint})`]: { ...baseTypography },
48
+ };
49
+ }
50
+ else if (isTablet) {
51
+ const existing = result[baseKey] || {};
52
+ result[baseKey] = {
53
+ ...existing,
54
+ [`@media (min-width: ${tabletBreakpoint})`]: { ...baseTypography },
55
+ };
56
+ }
57
+ else if (isMobile) {
58
+ const existing = result[baseKey] || {};
59
+ result[baseKey] = { ...baseTypography, ...existing };
60
+ }
61
+ else {
62
+ result[baseKey] = baseTypography;
63
+ }
64
+ }
65
+ return result;
66
+ }
67
+ function convertObjectKeysToCasedClassNames(typography, casing = casing_1.CASINGS.kebabCase, prefix = '') {
68
+ const mapKey = (key) => {
69
+ let className;
70
+ switch (casing) {
71
+ case casing_1.CASINGS.snakeCase:
72
+ className = (0, casing_1.toSnakeCase)(key);
73
+ break;
74
+ case casing_1.CASINGS.camelCase:
75
+ className = (0, casing_1.toCamelCase)(key);
76
+ break;
77
+ case casing_1.CASINGS.pascalCase:
78
+ className = (0, casing_1.toPascalCase)(key);
79
+ break;
80
+ case casing_1.CASINGS.kebabCase:
81
+ className = (0, casing_1.toKebabCase)(key);
82
+ break;
83
+ case casing_1.CASINGS.noCase:
84
+ className = (0, casing_1.toNoCase)(key);
85
+ break;
86
+ default:
87
+ console.error(`${casing} is currently not supported in this function, reverting to default ${casing_1.CASINGS.kebabCase}. Please raise an issue ticket here[https://github.com/mindvalley/mv-design-system]`);
88
+ className = (0, casing_1.toKebabCase)(key);
89
+ }
90
+ return prefix ? `.${prefix}${className}` : `.${className}`;
91
+ };
92
+ function mapVal(value) {
93
+ const res = {};
94
+ const variationSettings = [];
95
+ Object.keys(value).forEach((key) => {
96
+ const propValue = value[key];
97
+ if (key === 'lineHeight' && typeof propValue === 'string') {
98
+ res[key] = (0, dimens_1.lineHeightToRem)(propValue);
99
+ }
100
+ else if (['fontSize', 'letterSpacing'].includes(key) && typeof propValue === 'string') {
101
+ res[key] = (0, dimens_1.strPxToRemStr)(propValue);
102
+ }
103
+ else if (key === 'fontWidth' && typeof propValue === 'number') {
104
+ variationSettings.push(`"wdth" ${propValue}`);
105
+ }
106
+ else if (key === 'slant' && typeof propValue === 'number') {
107
+ variationSettings.push(`"slnt" ${propValue}`);
108
+ }
109
+ else if (typeof propValue === 'object' && propValue !== null) {
110
+ res[key] = mapVal(propValue);
111
+ }
112
+ else if (propValue !== undefined) {
113
+ res[key] = propValue;
114
+ }
115
+ });
116
+ if (variationSettings.length > 0) {
117
+ res.fontVariationSettings = variationSettings.join(', ');
118
+ }
119
+ return res;
120
+ }
121
+ return mapObj(typography, mapKey, mapVal);
122
+ }
123
+ function mapObj(obj, keyMapFn, valueMapFn) {
124
+ const result = {};
125
+ for (const [key, value] of Object.entries(obj)) {
126
+ result[keyMapFn(key)] = valueMapFn(value);
127
+ }
128
+ return result;
129
+ }
130
+ exports.default = plugin_1.default.withOptions(typographyPlugin);
package/docs/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Documentation
2
+
3
+ These guides cover how to use the Mindvalley Design System in your projects - from installing tokens to configuring Tailwind plugins for typography, colors, icons, and wordmarks.
4
+
5
+ ## Quick start
6
+
7
+ New here? Start with the [Usage Guide](usage.md) for installation and basic setup.
8
+
9
+ ## Guides
10
+
11
+ | Topic | Guide | What You'll Learn |
12
+ |-------|-------|-------------------|
13
+ | Colors | [Usage → Colors](usage.md#-colors) | Tailwind config, multi-brand setup, gradients |
14
+ | Typography | [Typography Guide](typography/README.md) | Font setup, class reference, plugin options |
15
+ | Icons | [Usage → Icons](usage.md#-icons) | Brand, UI, and category icons with sprites |
16
+ | Wordmarks | [Usage → Wordmarks](usage.md#-wordmarks) | Trainer and topic wordmarks |
17
+
18
+ ## Migration
19
+
20
+ - [Sharp Grotesk → Google Sans Flex](typography/migration.md) - Migrate to the new variable font system
21
+
22
+ ## Contributing
23
+
24
+ - [Development Guide](../CONTRIBUTING.md) - Setup, commits, build process
25
+ - [Release Process](releasing.md) - Semantic versioning and publishing
@@ -0,0 +1,84 @@
1
+ # Code Style
2
+
3
+ This project uses [Biome](https://biomejs.dev/) for formatting and linting.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npm run format # Format files
9
+ npm run lint # Lint files
10
+ npm run check # Format + lint + organize imports
11
+ npm run check:ci # CI check (no auto-fix)
12
+ ```
13
+
14
+ ## Formatting Rules
15
+
16
+ | Setting | Value |
17
+ |---------|-------|
18
+ | Indent | 2 spaces |
19
+ | Line width | 100 |
20
+ | Line ending | LF |
21
+ | Quotes | Single |
22
+ | JSX quotes | Double |
23
+ | Semicolons | As needed (omit when possible) |
24
+ | Trailing commas | ES5 |
25
+ | Arrow parens | Always |
26
+
27
+ ```typescript
28
+ // ✅ Correct
29
+ const example = (value: string) => {
30
+ return `Hello, ${value}`
31
+ }
32
+
33
+ // ❌ Wrong
34
+ const example = value => {
35
+ return "Hello, " + value;
36
+ };
37
+ ```
38
+
39
+ ## Linting Rules
40
+
41
+ ### Enforced
42
+
43
+ - `useConst` - Use `const` over `let` when variable is never reassigned
44
+ - `useTemplate` - Prefer template literals over string concatenation
45
+
46
+ ### Warnings
47
+
48
+ - `noExplicitAny` - Avoid `any` type
49
+ - `noNonNullAssertion` - Avoid `!` assertions
50
+ - `noConsole` - Avoid console statements
51
+
52
+ ### Allowed
53
+
54
+ - `forEach` - Array forEach is permitted
55
+
56
+ ## TypeScript
57
+
58
+ - **Strict mode** enabled
59
+ - Target: ES2022
60
+ - Module: Node16
61
+
62
+ ## Markdown
63
+
64
+ Linted with markdownlint. Run `npm run lint:md` to check.
65
+
66
+ - Max line length: 500
67
+ - Inline HTML allowed
68
+ - First line doesn't need to be h1
69
+
70
+ ## Helper Utilities
71
+
72
+ Available in `src/helpers/`:
73
+
74
+ | Function | Description |
75
+ |----------|-------------|
76
+ | `toKebabCase()` | Convert string to kebab-case |
77
+ | `toSnakeCase()` | Convert string to snake_case |
78
+ | `toCamelCase()` | Convert string to camelCase |
79
+ | `toPascalCase()` | Convert string to PascalCase |
80
+ | `toNoCase()` | Convert string to lowercase no separators |
81
+
82
+ ```typescript
83
+ import { toKebabCase } from '@mindvalley/design-system/helpers/casing'
84
+ ```
@@ -0,0 +1,79 @@
1
+ # Git Workflow
2
+
3
+ ## Branch Naming
4
+
5
+ Format: `JIRA-ID-description-in-kebab-case`
6
+
7
+ ```bash
8
+ # Examples
9
+ CRF-629-update-contribution-docs
10
+ MVHOME-765-add-tool-versions
11
+ ```
12
+
13
+ ## Commits
14
+
15
+ Use conventional commits. Run `npm run commit` for interactive prompts.
16
+
17
+ ### Commit Types
18
+
19
+ | Type | Description | Triggers Release |
20
+ |------|-------------|------------------|
21
+ | `feat` | New feature | Minor (1.x.0) |
22
+ | `fix` | Bug fix | Patch (1.0.x) |
23
+ | `perf` | Performance improvement | Patch |
24
+ | `docs` | Documentation only | No |
25
+ | `style` | Formatting, whitespace | No |
26
+ | `refactor` | Code change (no feature/fix) | No |
27
+ | `test` | Add/correct tests | No |
28
+ | `build` | Build system changes | No |
29
+ | `ci` | CI configuration | No |
30
+ | `chore` | Other changes | No |
31
+
32
+ ### Commit Message Format
33
+
34
+ ```
35
+ type(scope): Sentence case description
36
+
37
+ JIRA-ID
38
+ ```
39
+
40
+ **Important:** Subject must be sentence-case (commitlint enforces this).
41
+
42
+ ```bash
43
+ # ✅ Correct
44
+ fix: Correct broken documentation links
45
+
46
+ # ❌ Wrong
47
+ fix: correct broken documentation links
48
+ ```
49
+
50
+ ## Pull Requests
51
+
52
+ 1. Ensure working tree is clean
53
+ 2. Push branch with `-u` flag
54
+ 3. Use PR template from `.github/pull_request_template.md`
55
+ 4. Title format: `[JIRA-ID] Summary`
56
+
57
+ ### PR Template Structure
58
+
59
+ ```markdown
60
+ #### Link to Ticket: https://mindvalley.atlassian.net/browse/<JIRA_TICKET_NO>
61
+
62
+ ## Description
63
+ ## Screenshots
64
+ ## What is the expected behaviour?
65
+ ## How to test?
66
+ ```
67
+
68
+ ## CI Pipeline
69
+
70
+ On PR to `main`, CI runs:
71
+
72
+ 1. `npm ci` - Install dependencies
73
+ 2. `npm run lint:md` - Lint markdown
74
+ 3. `npm run build` - Build project
75
+ 4. `npm test` - Run tests
76
+
77
+ ## Releases
78
+
79
+ Automated via semantic-release on merge to `main`. See [releasing.md](../releasing.md) for details.
@@ -0,0 +1,65 @@
1
+ # Testing
2
+
3
+ This project uses [Jest](https://jestjs.io/) for testing.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npm run test # Run all tests
9
+ npm run test:watch # Watch mode
10
+ ```
11
+
12
+ ## Directory Structure
13
+
14
+ ```
15
+ __tests__/
16
+ ├── src/
17
+ │ ├── tailwind/
18
+ │ │ └── plugins/
19
+ │ └── types/
20
+ ├── utilities/
21
+ └── utils/
22
+ └── plugin.helpers.ts # Shared test utilities
23
+ ```
24
+
25
+ **Important:** Tests go in `__tests__/`, not `test/`.
26
+
27
+ ## Test Patterns
28
+
29
+ ### Schema Validation Tests
30
+
31
+ For Zod schemas, test both valid and invalid cases:
32
+
33
+ ```typescript
34
+ describe('ColorTokenSchema', () => {
35
+ it('should accept valid 6-digit hex color', () => {
36
+ const valid = { value: '#ff0000', type: 'color' as const }
37
+ expect(() => ColorTokenSchema.parse(valid)).not.toThrow()
38
+ expect(ColorTokenSchema.safeParse(valid).success).toBe(true)
39
+ })
40
+
41
+ it('should reject invalid hex color format', () => {
42
+ const invalid = { value: 'not-a-color', type: 'color' as const }
43
+ expect(() => ColorTokenSchema.parse(invalid)).toThrow()
44
+ expect(ColorTokenSchema.safeParse(invalid).success).toBe(false)
45
+ })
46
+ })
47
+ ```
48
+
49
+ ### Test Naming
50
+
51
+ - Use descriptive `it` statements starting with "should"
52
+ - Group related tests with `describe` blocks
53
+ - Test edge cases and error conditions
54
+
55
+ ### Path Aliases in Tests
56
+
57
+ Use the `@test-utils/*` alias for shared test utilities:
58
+
59
+ ```typescript
60
+ import { someHelper } from '@test-utils/plugin.helpers'
61
+ ```
62
+
63
+ ## Coverage
64
+
65
+ Coverage reports are generated in the `coverage/` directory (not committed to git).
@@ -0,0 +1,83 @@
1
+ # Token System
2
+
3
+ Design tokens are transformed from Figma → Supernova → JSON → JavaScript/Tailwind plugins.
4
+
5
+ ## Directory Structure
6
+
7
+ ```
8
+ src/tokens/brands/
9
+ ├── mindvalley/
10
+ │ ├── colors.json
11
+ │ └── typography.json
12
+ └── b2b/
13
+ ├── colors.json
14
+ └── typography.json
15
+ ```
16
+
17
+ ## Transformation Pipeline
18
+
19
+ ```
20
+ npm run validate-tokens → Zod validation
21
+ npm run build:styledictionary → style-dictionary transform
22
+ npm run build → Full build (validate + transform + bundle)
23
+ ```
24
+
25
+ ## Token Validation
26
+
27
+ Tokens are validated with Zod schemas before transformation. See [token-validation.md](../token-validation.md).
28
+
29
+ **Key schemas:** `src/types/token-schemas.ts`
30
+
31
+ ```typescript
32
+ // Token types must match exactly
33
+ { value: '#ff0000', type: 'color' } // ✅ Valid
34
+ { value: 'red', type: 'color' } // ❌ Invalid hex
35
+ { value: '#ff0000' } // ❌ Missing type
36
+ ```
37
+
38
+ ## Multi-Brand Support
39
+
40
+ Two brands are supported:
41
+
42
+ - **mindvalley** - Main brand
43
+ - **b2b** - B2B brand
44
+
45
+ Import the appropriate entry point:
46
+
47
+ ```typescript
48
+ import { colors } from '@mindvalley/design-system' // Mindvalley
49
+ import { colors } from '@mindvalley/design-system/b2b' // B2B
50
+ ```
51
+
52
+ ## Tailwind Plugins
53
+
54
+ Located in `src/tailwind/plugins/`:
55
+
56
+ - `typography.ts` - Typography utilities
57
+ - `typography-gsf.ts` - Google Sans Font typography
58
+ - `tokens/` - Token-based color/typography plugins
59
+
60
+ ## Build Outputs
61
+
62
+ After `npm run build`, outputs go to `dist/`:
63
+
64
+ ```
65
+ dist/
66
+ ├── index.js # Main entry (Mindvalley brand)
67
+ ├── b2b.js # B2B brand entry
68
+ ├── helpers/ # Helper utilities
69
+ └── tailwind/ # Tailwind plugins
70
+ ```
71
+
72
+ ## Figma Sync
73
+
74
+ Icons and wordmarks sync from Figma:
75
+
76
+ ```bash
77
+ npm run build:figma # Requires FIGMA_TOKEN in .env
78
+ ```
79
+
80
+ Configuration files:
81
+
82
+ - `src/utilities/svg-import/.figma_icons.ts`
83
+ - `src/utilities/svg-import/.figma_wordmarks.ts`
@@ -1,13 +1,13 @@
1
- ## Releasing 🚀
1
+ # Releasing 🚀
2
2
 
3
3
  By default, semantic-release uses the [Angular Commit Message Conventions](https://www.conventionalcommits.org/en/v1.0.0-beta.4/) and triggers releases based on the following rules:
4
4
 
5
- | Commit | Release Type | Semver update type |
6
- |-----------------------------|------------------|----------------------------------|
7
- | Commit with breaking change | Breaking release | Major release e.g 1.x.x -> 2.x.x |
8
- | Commit with type `feat` | Feature release | Major release e.g 1.x.x -> 2.x.x |
9
- | Commit with type `fix` | Fix Release | Minor release e.g 1.2.x -> 1.3.x |
10
- | Commit with type `perf` | Patch release | Patch release e.g 1.x.4 -> 1.x.5 |
5
+ | Commit | Release Type | Semver update type |
6
+ |-----------------------------|------------------|-----------------------------------|
7
+ | Commit with breaking change | Breaking release | Major release e.g 1.x.x -> 2.x.x |
8
+ | Commit with type `feat` | Feature release | Minor release e.g 1.2.x -> 1.3.x |
9
+ | Commit with type `fix` | Fix release | Patch release e.g 1.2.3 -> 1.2.4 |
10
+ | Commit with type `perf` | Performance fix | Patch release e.g 1.2.3 -> 1.2.4 |
11
11
 
12
12
  Only the above type of commits will trigger a release.
13
13
 
@@ -23,7 +23,7 @@ More detailed explanation can be found on the [semantic release steps documentat
23
23
 
24
24
  After release and publishing, the package should be available as a [scoped npm package](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages) and is on npm as [@mindvalley/design-system](https://www.npmjs.com/package/@mindvalley/design-system).
25
25
 
26
- ### Trusted publishing
26
+ ## Trusted publishing
27
27
 
28
28
  Releases run through the GitHub Actions workflow [`release.yml`](../.github/workflows/release.yml) using [npm trusted publishing](https://docs.npmjs.com/trusted-publishers). The workflow:
29
29
 
@@ -34,4 +34,4 @@ Releases run through the GitHub Actions workflow [`release.yml`](../.github/work
34
34
 
35
35
  If the workflow fails, re-run it from the Actions tab after addressing the underlying error. No manual npm publishing is expected under normal circumstances.
36
36
 
37
- Jump to the [usage guide](USAGE.md) to understand how to use the published package in your repo.
37
+ Jump to the [usage guide](usage.md) to understand how to use the published package in your repo.