@shohojdhara/atomix 0.3.2 → 0.3.4

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 (84) hide show
  1. package/README.md +58 -21
  2. package/dist/atomix.css +96 -121
  3. package/dist/atomix.min.css +3 -3
  4. package/dist/index.d.ts +7937 -7765
  5. package/dist/index.esm.js +3677 -4031
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +3648 -3952
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.js +1 -1
  10. package/dist/index.min.js.map +1 -1
  11. package/package.json +44 -16
  12. package/scripts/atomix-cli.js +1764 -0
  13. package/scripts/build-themes.js +208 -0
  14. package/scripts/cli/interactive-init.js +520 -0
  15. package/scripts/cli/migration-tools.js +603 -0
  16. package/scripts/cli/theme-bridge.js +129 -0
  17. package/scripts/cli/token-manager.js +519 -0
  18. package/scripts/sync-theme-config.js +309 -0
  19. package/src/components/Button/Button.tsx +36 -1
  20. package/src/components/List/ListGroup.tsx +1 -2
  21. package/src/components/Popover/Popover.tsx +2 -2
  22. package/src/components/Tooltip/Tooltip.stories.tsx +49 -12
  23. package/src/components/Tooltip/Tooltip.tsx +32 -58
  24. package/src/lib/composables/useTooltip.ts +285 -0
  25. package/src/lib/config/index.ts +275 -0
  26. package/src/lib/config/loader.ts +105 -0
  27. package/src/lib/constants/cssVariables.ts +390 -0
  28. package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +151 -0
  29. package/src/lib/hooks/index.ts +19 -0
  30. package/src/lib/hooks/useComponentCustomization.ts +175 -0
  31. package/src/lib/index.ts +14 -1
  32. package/src/lib/patterns/__tests__/slots.test.ts +108 -0
  33. package/src/lib/patterns/index.ts +35 -0
  34. package/src/lib/patterns/slots.tsx +421 -0
  35. package/src/lib/theme/composeTheme.ts +0 -5
  36. package/src/lib/theme/config/index.ts +1 -1
  37. package/src/lib/theme/config/loader.ts +75 -41
  38. package/src/lib/theme/config/types.ts +21 -7
  39. package/src/lib/theme/config/validator.ts +1 -1
  40. package/src/lib/theme/constants.ts +12 -2
  41. package/src/lib/theme/createTheme.ts +2 -135
  42. package/src/lib/theme/createThemeFromConfig.ts +132 -0
  43. package/src/lib/theme/cssVariableMapper.ts +261 -0
  44. package/src/lib/theme/devtools/CLI.ts +161 -76
  45. package/src/lib/theme/devtools/Comparator.tsx +343 -0
  46. package/src/lib/theme/devtools/IMPROVEMENTS.md +429 -0
  47. package/src/lib/theme/devtools/Inspector.tsx +21 -6
  48. package/src/lib/theme/devtools/LiveEditor.tsx +393 -0
  49. package/src/lib/theme/devtools/README.md +433 -0
  50. package/src/lib/theme/devtools/index.ts +12 -11
  51. package/src/lib/theme/generateCSSVariables.ts +79 -38
  52. package/src/lib/theme/index.ts +45 -246
  53. package/src/lib/theme/runtime/ThemeApplicator.ts +252 -0
  54. package/src/lib/theme/runtime/ThemeManager.test.ts +17 -1
  55. package/src/lib/theme/runtime/ThemeManager.ts +7 -7
  56. package/src/lib/theme/themeUtils.ts +27 -5
  57. package/src/lib/theme/types.ts +59 -1
  58. package/src/lib/theme-tools.ts +125 -0
  59. package/src/lib/types/components.ts +260 -72
  60. package/src/lib/types/partProps.ts +426 -0
  61. package/src/lib/utils/__tests__/componentUtils.test.ts +144 -0
  62. package/src/lib/utils/componentUtils.ts +163 -0
  63. package/src/lib/utils/index.ts +17 -57
  64. package/src/styles/01-settings/_settings.colors.scss +10 -10
  65. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  66. package/src/styles/01-settings/_settings.tooltip.scss +1 -1
  67. package/src/styles/03-generic/_generated-root.css +5 -0
  68. package/src/styles/06-components/_components.navbar.scss +12 -5
  69. package/src/styles/06-components/_components.tooltip.scss +31 -81
  70. package/src/themes/README.md +442 -0
  71. package/src/themes/themes.config.js +35 -0
  72. package/src/lib/theme/errors.test.ts +0 -207
  73. package/src/lib/theme/generators/CSSGenerator.ts +0 -311
  74. package/src/lib/theme/generators/ConfigGenerator.ts +0 -287
  75. package/src/lib/theme/generators/TypeGenerator.ts +0 -228
  76. package/src/lib/theme/generators/index.ts +0 -21
  77. package/src/lib/theme/monitoring/ThemeAnalytics.ts +0 -409
  78. package/src/lib/theme/monitoring/index.ts +0 -17
  79. package/src/lib/theme/overrides/ComponentOverrides.ts +0 -243
  80. package/src/lib/theme/overrides/index.ts +0 -15
  81. package/src/lib/theme/studio/ThemeStudio.tsx +0 -312
  82. package/src/lib/theme/studio/index.ts +0 -8
  83. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +0 -364
  84. package/src/lib/theme/whitelabel/index.ts +0 -13
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Component Utilities
3
+ *
4
+ * Helper functions for component development with the new customization system
5
+ */
6
+
7
+ import React from 'react';
8
+ import type { PartStyleProps } from '../types/partProps';
9
+ import { cssVarsToStyle } from '../theme/cssVariableMapper';
10
+
11
+ /**
12
+ * Merge multiple class names
13
+ */
14
+ export function mergeClassNames(...classes: Array<string | undefined | null | false>): string {
15
+ return classes.filter(Boolean).join(' ');
16
+ }
17
+
18
+ /**
19
+ * Apply part styles to element props
20
+ */
21
+ export function applyPartStyles<T extends { className?: string; style?: React.CSSProperties }>(
22
+ baseProps: T,
23
+ partStyles?: PartStyleProps
24
+ ): T {
25
+ if (!partStyles) return baseProps;
26
+
27
+ return {
28
+ ...baseProps,
29
+ className: mergeClassNames(baseProps.className, partStyles.className),
30
+ style: { ...baseProps.style, ...partStyles.style },
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Create style object from CSS variables
36
+ */
37
+ export function createCSSVarStyle(
38
+ cssVars?: Record<string, string | number>,
39
+ baseStyle?: React.CSSProperties
40
+ ): React.CSSProperties {
41
+ if (!cssVars) return baseStyle || {};
42
+
43
+ const varStyle = cssVarsToStyle(cssVars);
44
+ return { ...varStyle, ...baseStyle };
45
+ }
46
+
47
+ /**
48
+ * Merge component props with customization
49
+ */
50
+ export interface MergePropsOptions {
51
+ className?: string;
52
+ style?: React.CSSProperties;
53
+ cssVars?: Record<string, string | number>;
54
+ parts?: Record<string, PartStyleProps>;
55
+ }
56
+
57
+ export function mergeComponentProps<T extends { className?: string; style?: React.CSSProperties }>(
58
+ baseProps: T,
59
+ customization: MergePropsOptions
60
+ ): T {
61
+ const { className, style, cssVars, parts } = customization;
62
+
63
+ // Merge CSS variables into style
64
+ const cssVarStyle = cssVars ? cssVarsToStyle(cssVars) : {};
65
+
66
+ return {
67
+ ...baseProps,
68
+ className: mergeClassNames(baseProps.className, className),
69
+ style: {
70
+ ...cssVarStyle,
71
+ ...baseProps.style,
72
+ ...style,
73
+ },
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Get part styles from parts object
79
+ */
80
+ export function getPartStyles(
81
+ parts: Record<string, PartStyleProps> | undefined,
82
+ partName: string
83
+ ): PartStyleProps | undefined {
84
+ return parts?.[partName];
85
+ }
86
+
87
+ /**
88
+ * Create element props with part styles
89
+ */
90
+ export function createPartProps<T extends { className?: string; style?: React.CSSProperties }>(
91
+ baseClassName: string,
92
+ partStyles?: PartStyleProps,
93
+ additionalProps?: Partial<T>
94
+ ): T {
95
+ return {
96
+ ...additionalProps,
97
+ className: mergeClassNames(baseClassName, partStyles?.className),
98
+ style: { ...partStyles?.style, ...(additionalProps as any)?.style },
99
+ } as T;
100
+ }
101
+
102
+ /**
103
+ * Check if component has customization
104
+ */
105
+ export function hasCustomization(props: {
106
+ parts?: any;
107
+ cssVars?: any;
108
+ slots?: any;
109
+ }): boolean {
110
+ return Boolean(props.parts || props.cssVars || props.slots);
111
+ }
112
+
113
+ /**
114
+ * Create data attributes for debugging
115
+ */
116
+ export function createDebugAttrs(componentName: string, variant?: string): Record<string, string> {
117
+ if (process.env.NODE_ENV !== 'development') return {};
118
+
119
+ return {
120
+ 'data-component': componentName,
121
+ ...(variant && { 'data-variant': variant }),
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Generate a UUID v4
127
+ */
128
+ export function generateUUID(): string {
129
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
130
+ const r = (Math.random() * 16) | 0;
131
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
132
+ return v.toString(16);
133
+ });
134
+ }
135
+
136
+ /**
137
+ * Check if a URL is a YouTube URL
138
+ */
139
+ export function isYouTubeUrl(url: string): boolean {
140
+ const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/;
141
+ return youtubeRegex.test(url);
142
+ }
143
+
144
+ /**
145
+ * Extract YouTube video ID from URL
146
+ */
147
+ export function extractYouTubeId(url: string): string | null {
148
+ if (!isYouTubeUrl(url)) return null;
149
+
150
+ const patterns = [
151
+ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\n?#]+)/,
152
+ /youtube\.com\/.*[?&]v=([^&\n?#]+)/,
153
+ ];
154
+
155
+ for (const pattern of patterns) {
156
+ const match = url.match(pattern);
157
+ if (match && match[1]) {
158
+ return match[1];
159
+ }
160
+ }
161
+
162
+ return null;
163
+ }
@@ -1,61 +1,21 @@
1
- // Export DOM utilities
2
- export * from './dom';
3
-
4
- // Export other utilities as needed
5
-
6
- // Export icon utilities
7
- export * from './icons';
8
-
9
- import classNames from 'classnames';
10
-
11
1
  /**
12
- * Class name utility function to conditionally join classNames together.
13
- * This is a wrapper around the 'classnames' library and supports all its features:
14
- * - Strings and numbers
15
- * - Arrays (including nested arrays)
16
- * - Objects (keys are class names, values are truthy/falsy conditions)
17
- * - Mixed types
18
- *
19
- * @example
20
- * cn('foo', 'bar'); // 'foo bar'
21
- * cn('foo', { bar: true }); // 'foo bar'
22
- * cn({ 'foo-bar': true }); // 'foo-bar'
23
- * cn(['foo', { bar: true }]); // 'foo bar'
2
+ * Utility Functions Exports
24
3
  */
25
- export function cn(...args: any[]): string {
26
- return classNames(...args);
27
- }
28
4
 
29
- /**
30
- * Generate a UUID v4 compatible string without relying on Node.js crypto
31
- * This is a browser-compatible alternative to the uuid package
32
- * @returns A UUID v4 compatible string
33
- */
34
- export function generateUUID(): string {
35
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
36
- const r = (Math.random() * 16) | 0;
37
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
38
- return v.toString(16);
39
- });
40
- }
5
+ export {
6
+ mergeClassNames,
7
+ applyPartStyles,
8
+ createCSSVarStyle,
9
+ mergeComponentProps,
10
+ getPartStyles,
11
+ createPartProps,
12
+ hasCustomization,
13
+ createDebugAttrs,
14
+ generateUUID,
15
+ isYouTubeUrl,
16
+ extractYouTubeId,
17
+ } from './componentUtils';
41
18
 
42
- /**
43
- * Extract YouTube video ID from various YouTube URL formats
44
- * @param url - YouTube URL
45
- * @returns YouTube video ID or null if not found
46
- */
47
- export function extractYouTubeId(url: string): string | null {
48
- const regex =
49
- /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/;
50
- const match = url.match(regex);
51
- return match ? (match[1] as string) : null;
52
- }
53
-
54
- /**
55
- * Check if a URL is a YouTube URL
56
- * @param url - URL to check
57
- * @returns True if the URL is a YouTube URL
58
- */
59
- export function isYouTubeUrl(url: string): boolean {
60
- return /(?:youtube\.com|youtu\.be)/.test(url);
61
- }
19
+ export type {
20
+ MergePropsOptions,
21
+ } from './componentUtils';
@@ -12,16 +12,16 @@ $color-contrast-dark: #000000 !default;
12
12
  $color-contrast-light: #ffffff !default;
13
13
 
14
14
  // Primitives Primary Colors
15
- $primary-1: #f2e8fd !default;
16
- $primary-2: #e4d0fa !default;
17
- $primary-3: #d0b2f5 !default;
18
- $primary-4: #b88cef !default;
19
- $primary-5: #9c63e9 !default;
20
- $primary-6: #7c3aed !default; // Balanced primary purple
21
- $primary-7: #6425ca !default;
22
- $primary-8: #501ba6 !default;
23
- $primary-9: #3c1583 !default;
24
- $primary-10: #2a0e60 !default;
15
+ $primary-1: #fff9e6 !default;
16
+ $primary-2: #fff4cc !default;
17
+ $primary-3: #ffe699 !default;
18
+ $primary-4: #ffd966 !default;
19
+ $primary-5: #ffcc33 !default;
20
+ $primary-6: #ffb800 !default; // Balanced primary - main brand color (WCAG AA compliant)
21
+ $primary-7: #e6a600 !default;
22
+ $primary-8: #cc9400 !default;
23
+ $primary-9: #b38200 !default;
24
+ $primary-10: #997000 !default;
25
25
 
26
26
  // Primitives Red Colors
27
27
  $red-1: #fef2f2 !default;
@@ -24,7 +24,7 @@ $navbar-brand-font-weight: $font-weight-bold !default;
24
24
  $navbar-brand-color: var(--#{$prefix}body-color) !default;
25
25
 
26
26
  // Mobile toggler
27
- $navbar-toggler-size: 30px !default;
27
+ $navbar-toggler-size: 2rem !default;
28
28
  $navbar-toggler-color: var(--#{$prefix}body-color) !default;
29
29
  $navbar-toggler-bg: transparent !default;
30
30
  $navbar-toggler-border: 0 !default;
@@ -11,7 +11,7 @@ $tooltip-bg: var(--#{config.$prefix}invert-bg-subtle) !default;
11
11
 
12
12
  $tooltip-font-size: typography.$font-size-xs !default;
13
13
  $tooltip-font-weight: typography.$font-weight-normal !default;
14
- $tooltip-color: var(--#{config.$prefix}invert-text) !default;
14
+ $tooltip-color: var(--#{config.$prefix}body-bg) !default;
15
15
 
16
16
  $tooltip-border-radius: borderRadius.$border-radius !default;
17
17
  $tooltip-border-width: null !default;
@@ -0,0 +1,5 @@
1
+ /* AUTO-GENERATED - DO NOT EDIT MANUALLY */
2
+
3
+ :root {
4
+ --atomix-colors-primary-main: #3b82f6;
5
+ }
@@ -48,6 +48,12 @@
48
48
  max-width: var(--#{$prefix}navbar-container-max-width);
49
49
  padding: 0 var(--#{$prefix}navbar-padding-x);
50
50
  margin: 0 auto;
51
+ gap: var(--#{$prefix}navbar-padding-x);
52
+
53
+ @include media.media-down('md') {
54
+ flex-wrap: nowrap;
55
+ gap: 0.5rem;
56
+ }
51
57
  }
52
58
 
53
59
  // 3. Element Styles (BEM Elements)
@@ -72,6 +78,7 @@
72
78
  }
73
79
 
74
80
  &__toggler {
81
+ position: relative;
75
82
  display: none;
76
83
  align-items: center;
77
84
  justify-content: center;
@@ -99,17 +106,13 @@
99
106
 
100
107
  &-icon {
101
108
  position: relative;
102
- display: inline-block;
103
- width: 1.5em;
104
- height: 1.5em;
105
- vertical-align: middle;
106
109
 
107
110
  &::before,
108
111
  &::after,
109
112
  & {
110
113
  position: absolute;
111
114
  height: 2px;
112
- width: 100%;
115
+ width: var(--#{$prefix}navbar-toggler-size);
113
116
  background-color: var(--#{$prefix}navbar-toggler-color);
114
117
  border-radius: 1px;
115
118
  transition: transform 0.15s ease;
@@ -228,6 +231,10 @@
228
231
  #{$root}__collapse {
229
232
  display: flex !important;
230
233
  }
234
+
235
+ #{$root}__toggler {
236
+ display: none !important;
237
+ }
231
238
  }
232
239
  }
233
240
 
@@ -3,6 +3,7 @@
3
3
  @use '../02-tools/tools.rem' as *;
4
4
  @use '../02-tools/tools.size' as *;
5
5
  @use '../02-tools/tools.background' as *;
6
+ @use '../01-settings/settings.z-layers' as *;
6
7
 
7
8
  .c-tooltip {
8
9
  $root: &;
@@ -20,59 +21,14 @@
20
21
  --#{$prefix}tooltip-box-shadow: #{$tooltip-box-shadow};
21
22
  --#{$prefix}tooltip-arrow-size: #{rem($tooltip-arrow-size)};
22
23
  --#{$prefix}tooltip-offset: #{rem($tooltip-arrow-size)}; // Default offset
24
+ --#{$prefix}z-index-tooltip: #{$z-index-tooltip};
23
25
 
24
26
  position: absolute;
25
27
  width: max-content;
26
28
  height: max-content;
27
29
  max-width: var(--#{$prefix}tooltip-max-width);
28
30
  pointer-events: none; // Wrapper shouldn't block clicks, but content might
29
- z-index: 1000;
30
-
31
- // Base positioning logic
32
- &--top,
33
- &--top-left,
34
- &--top-right {
35
- bottom: calc(100% + var(--#{$prefix}tooltip-offset));
36
- transform-origin: bottom center;
37
- }
38
-
39
- &--bottom,
40
- &--bottom-left,
41
- &--bottom-right {
42
- top: calc(100% + var(--#{$prefix}tooltip-offset));
43
- transform-origin: top center;
44
- }
45
-
46
- &--left {
47
- right: calc(100% + var(--#{$prefix}tooltip-offset));
48
- top: 50%;
49
- transform: translateY(-50%);
50
- transform-origin: right center;
51
- }
52
-
53
- &--right {
54
- left: calc(100% + var(--#{$prefix}tooltip-offset));
55
- top: 50%;
56
- transform: translateY(-50%);
57
- transform-origin: left center;
58
- }
59
-
60
- // Horizontal alignment for top/bottom
61
- &--top,
62
- &--bottom {
63
- left: 50%;
64
- transform: translateX(-50%);
65
- }
66
-
67
- &--top-left,
68
- &--bottom-left {
69
- left: 0;
70
- }
71
-
72
- &--top-right,
73
- &--bottom-right {
74
- right: 0;
75
- }
31
+ z-index: var(--#{$prefix}z-index-tooltip);
76
32
 
77
33
  &__content {
78
34
  position: relative;
@@ -106,50 +62,44 @@
106
62
  position: absolute;
107
63
  width: var(--#{$prefix}tooltip-arrow-size);
108
64
  height: var(--#{$prefix}tooltip-arrow-size);
65
+ border-radius: calc(
66
+ (var(--#{$prefix}tooltip-arrow-size) - var(--#{$prefix}tooltip-border-radius)) / 2
67
+ );
109
68
  @include dynamic-background(var(--#{$prefix}tooltip-bg));
110
69
  z-index: 1;
111
70
  transform: rotate(45deg);
112
71
  }
113
72
 
114
- // Arrow positioning
115
- &--top &__arrow,
116
- &--top-left &__arrow,
117
- &--top-right &__arrow {
118
- bottom: calc(var(--#{$prefix}tooltip-arrow-size) / -2);
119
- }
120
-
121
- &--bottom &__arrow,
122
- &--bottom-left &__arrow,
123
- &--bottom-right &__arrow {
124
- top: calc(var(--#{$prefix}tooltip-arrow-size) / -2);
125
- }
126
-
127
- &--left &__arrow {
128
- right: calc(var(--#{$prefix}tooltip-arrow-size) / -2);
129
- top: 50%;
130
- transform: translateY(-50%) rotate(45deg);
131
- }
132
-
73
+ &--left &__arrow,
133
74
  &--right &__arrow {
134
- left: calc(var(--#{$prefix}tooltip-arrow-size) / -2);
135
- top: 50%;
136
- transform: translateY(-50%) rotate(45deg);
75
+ transform: rotate(45deg);
137
76
  }
138
77
 
139
- // Arrow horizontal alignment
140
- &--top &__arrow,
141
- &--bottom &__arrow {
142
- left: 50%;
143
- transform: translateX(-50%) rotate(45deg);
78
+ &--top &__arrow {
79
+ transform: rotate(45deg);
144
80
  }
145
81
 
146
- &--top-left &__arrow,
147
- &--bottom-left &__arrow {
148
- left: var(--#{$prefix}tooltip-arrow-size);
82
+ &--bottom &__arrow {
83
+ transform: rotate(225deg);
149
84
  }
150
85
 
151
- &--top-right &__arrow,
152
- &--bottom-right &__arrow {
153
- right: var(--#{$prefix}tooltip-arrow-size);
86
+ &--glass {
87
+ z-index: unset;
88
+ #{$root}__content {
89
+ @include dynamic-background(
90
+ var(--#{$prefix}tooltip-bg),
91
+ $background-transparency-enable: true,
92
+ $transparency: 0.4
93
+ );
94
+ }
95
+ #{$root}__arrow {
96
+ @include dynamic-background(
97
+ var(--#{$prefix}tooltip-bg),
98
+ $background-transparency-enable: true,
99
+ $transparency: 0.4
100
+ );
101
+ clip-path: polygon(0 100%, 100% 100%, 100% 0);
102
+ backdrop-filter: var(--atomix-glass-container-backdrop);
103
+ }
154
104
  }
155
- }
105
+ }