@shohojdhara/atomix 0.2.3 → 0.2.5
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.
- package/README.md +19 -0
- package/dist/atomix.css +1703 -1544
- package/dist/atomix.min.css +4 -4
- package/dist/index.d.ts +1465 -963
- package/dist/index.esm.js +16289 -25908
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +15650 -21780
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/applemix.css +15008 -0
- package/dist/themes/applemix.min.css +72 -0
- package/dist/themes/boomdevs.css +1608 -1450
- package/dist/themes/boomdevs.min.css +5 -5
- package/dist/themes/esrar.css +1702 -1543
- package/dist/themes/esrar.min.css +4 -4
- package/dist/themes/flashtrade.css +15159 -0
- package/dist/themes/flashtrade.min.css +86 -0
- package/dist/themes/mashroom.css +1699 -1540
- package/dist/themes/mashroom.min.css +7 -7
- package/dist/themes/shaj-default.css +1693 -1534
- package/dist/themes/shaj-default.min.css +4 -4
- package/package.json +6 -17
- package/src/components/Accordion/Accordion.stories.tsx +662 -21
- package/src/components/Accordion/Accordion.tsx +21 -14
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
- package/src/components/AtomixGlass/AtomixGlass.tsx +529 -1195
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +400 -0
- package/src/components/AtomixGlass/GlassFilter.tsx +156 -0
- package/src/components/AtomixGlass/README.md +124 -2
- package/src/components/AtomixGlass/atomixGLass.old.tsx +1266 -0
- package/src/components/AtomixGlass/glass-utils.ts +263 -0
- package/src/components/AtomixGlass/shader-utils.ts +792 -68
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1250 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +5768 -0
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1129 -0
- package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +395 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +301 -0
- package/src/components/AtomixGlass/utils.ts +3 -3
- package/src/components/Avatar/Avatar.tsx +3 -0
- package/src/components/Avatar/AvatarGroup.tsx +2 -1
- package/src/components/Badge/Badge.stories.tsx +76 -55
- package/src/components/Badge/Badge.tsx +12 -14
- package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
- package/src/components/Button/Button.stories.tsx +501 -20
- package/src/components/Button/Button.tsx +5 -8
- package/src/components/Callout/Callout.stories.tsx +86 -35
- package/src/components/Callout/Callout.tsx +31 -9
- package/src/components/Card/Card.stories.tsx +565 -2
- package/src/components/Card/Card.tsx +15 -4
- package/src/components/Card/ElevationCard.tsx +2 -0
- package/src/components/Chart/AnimatedChart.tsx +179 -156
- package/src/components/Chart/AreaChart.tsx +123 -12
- package/src/components/Chart/BarChart.tsx +91 -100
- package/src/components/Chart/BaseChart.tsx +80 -0
- package/src/components/Chart/BubbleChart.tsx +114 -290
- package/src/components/Chart/CandlestickChart.tsx +282 -622
- package/src/components/Chart/Chart.stories.tsx +576 -179
- package/src/components/Chart/Chart.tsx +374 -75
- package/src/components/Chart/ChartRenderer.tsx +371 -220
- package/src/components/Chart/ChartToolbar.tsx +372 -61
- package/src/components/Chart/ChartTooltip.tsx +33 -18
- package/src/components/Chart/DonutChart.tsx +172 -254
- package/src/components/Chart/FunnelChart.tsx +169 -240
- package/src/components/Chart/GaugeChart.tsx +224 -392
- package/src/components/Chart/HeatmapChart.tsx +302 -440
- package/src/components/Chart/LineChart.tsx +148 -103
- package/src/components/Chart/MultiAxisChart.tsx +267 -395
- package/src/components/Chart/PieChart.tsx +114 -64
- package/src/components/Chart/RadarChart.tsx +202 -218
- package/src/components/Chart/ScatterChart.tsx +111 -97
- package/src/components/Chart/TreemapChart.tsx +147 -222
- package/src/components/Chart/WaterfallChart.tsx +253 -291
- package/src/components/Chart/index.ts +11 -9
- package/src/components/Chart/types.ts +85 -9
- package/src/components/Chart/utils.ts +66 -0
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +6 -3
- package/src/components/Countdown/Countdown.tsx +4 -0
- package/src/components/DataTable/DataTable.tsx +2 -1
- package/src/components/DatePicker/DatePicker.stories.tsx +689 -12
- package/src/components/DatePicker/DatePicker.tsx +3 -9
- package/src/components/DatePicker/types.ts +5 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
- package/src/components/Dropdown/Dropdown.tsx +26 -28
- package/src/components/EdgePanel/EdgePanel.stories.tsx +473 -2
- package/src/components/EdgePanel/EdgePanel.tsx +101 -13
- package/src/components/Footer/Footer.stories.tsx +187 -60
- package/src/components/Footer/Footer.test.tsx +134 -0
- package/src/components/Footer/Footer.tsx +133 -34
- package/src/components/Footer/FooterLink.tsx +1 -1
- package/src/components/Footer/FooterSection.tsx +53 -36
- package/src/components/Footer/FooterSocialLink.tsx +32 -29
- package/src/components/Footer/README.md +82 -3
- package/src/components/Footer/index.ts +1 -1
- package/src/components/Form/Checkbox.stories.tsx +13 -5
- package/src/components/Form/Checkbox.tsx +3 -6
- package/src/components/Form/Form.stories.tsx +10 -3
- package/src/components/Form/Form.tsx +2 -0
- package/src/components/Form/FormGroup.tsx +2 -1
- package/src/components/Form/Input.stories.tsx +12 -11
- package/src/components/Form/Input.tsx +97 -95
- package/src/components/Form/Radio.stories.tsx +22 -7
- package/src/components/Form/Radio.tsx +3 -6
- package/src/components/Form/Select.stories.tsx +21 -6
- package/src/components/Form/Select.tsx +3 -5
- package/src/components/Form/Textarea.stories.tsx +13 -11
- package/src/components/Form/Textarea.tsx +88 -86
- package/src/components/Hero/Hero.stories.tsx +2 -3
- package/src/components/Hero/Hero.tsx +5 -6
- package/src/components/Icon/Icon.tsx +12 -1
- package/src/components/List/List.tsx +2 -1
- package/src/components/List/ListGroup.tsx +2 -1
- package/src/components/Messages/Messages.stories.tsx +113 -0
- package/src/components/Messages/Messages.tsx +52 -9
- package/src/components/Modal/Modal.stories.tsx +48 -32
- package/src/components/Modal/Modal.tsx +19 -24
- package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
- package/src/components/Navigation/Menu/Menu.tsx +2 -2
- package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
- package/src/components/Navigation/Nav/Nav.tsx +22 -4
- package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
- package/src/components/Navigation/Navbar/Navbar.tsx +70 -29
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
- package/src/components/Navigation/SideMenu/SideMenu.tsx +29 -2
- package/src/components/Pagination/Pagination.stories.tsx +13 -6
- package/src/components/Pagination/Pagination.tsx +7 -6
- package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
- package/src/components/Popover/Popover.stories.tsx +32 -24
- package/src/components/Popover/Popover.tsx +4 -1
- package/src/components/ProductReview/ProductReview.tsx +8 -2
- package/src/components/Progress/Progress.tsx +19 -3
- package/src/components/Rating/Rating.stories.tsx +11 -6
- package/src/components/Rating/Rating.tsx +3 -5
- package/src/components/River/River.tsx +5 -5
- package/src/components/SectionIntro/SectionIntro.tsx +8 -2
- package/src/components/Slider/Slider.stories.tsx +4 -4
- package/src/components/Slider/Slider.tsx +4 -3
- package/src/components/Spinner/Spinner.tsx +19 -3
- package/src/components/Steps/Steps.stories.tsx +5 -4
- package/src/components/Steps/Steps.tsx +8 -5
- package/src/components/Tab/Tab.stories.tsx +4 -3
- package/src/components/Tab/Tab.tsx +8 -6
- package/src/components/Testimonial/Testimonial.tsx +8 -2
- package/src/components/Todo/Todo.tsx +2 -1
- package/src/components/Toggle/Toggle.stories.tsx +5 -4
- package/src/components/Toggle/Toggle.tsx +8 -5
- package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
- package/src/components/Tooltip/Tooltip.tsx +9 -2
- package/src/components/Upload/Upload.stories.tsx +252 -0
- package/src/components/Upload/Upload.tsx +92 -53
- package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
- package/src/components/index.ts +0 -4
- package/src/layouts/Grid/Grid.stories.tsx +10 -23
- package/src/layouts/Grid/Grid.tsx +20 -1
- package/src/layouts/Grid/GridCol.tsx +76 -48
- package/src/lib/composables/useAtomixGlass.ts +861 -44
- package/src/lib/composables/useBarChart.ts +21 -4
- package/src/lib/composables/useChart.ts +227 -370
- package/src/lib/composables/useChartExport.ts +19 -78
- package/src/lib/composables/useChartToolbar.ts +11 -21
- package/src/lib/composables/useEdgePanel.ts +125 -71
- package/src/lib/composables/useFooter.ts +3 -3
- package/src/lib/composables/useGlassContainer.ts +16 -7
- package/src/lib/composables/useLineChart.ts +11 -2
- package/src/lib/composables/usePieChart.ts +4 -14
- package/src/lib/composables/useRiver.ts +5 -0
- package/src/lib/composables/useSlider.ts +62 -24
- package/src/lib/composables/useVideoPlayer.ts +60 -63
- package/src/lib/constants/components.ts +147 -32
- package/src/lib/types/components.ts +355 -25
- package/src/lib/utils/displacement-generator.ts +55 -49
- package/src/lib/utils/icons.ts +1 -1
- package/src/lib/utils/index.ts +16 -10
- package/src/styles/01-settings/_settings.accordion.scss +19 -19
- package/src/styles/01-settings/_settings.animations.scss +5 -5
- package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
- package/src/styles/01-settings/_settings.avatar.scss +17 -17
- package/src/styles/01-settings/_settings.background.scss +0 -3
- package/src/styles/01-settings/_settings.badge.scss +1 -1
- package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
- package/src/styles/01-settings/_settings.card.scss +1 -1
- package/src/styles/01-settings/_settings.chart.scss +65 -2
- package/src/styles/01-settings/_settings.dropdown.scss +1 -1
- package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
- package/src/styles/01-settings/_settings.footer.scss +35 -42
- package/src/styles/01-settings/_settings.input.scss +1 -1
- package/src/styles/01-settings/_settings.list.scss +1 -1
- package/src/styles/01-settings/_settings.rating.scss +1 -1
- package/src/styles/01-settings/_settings.tabs.scss +1 -1
- package/src/styles/01-settings/_settings.upload.scss +6 -5
- package/src/styles/02-tools/_tools.animations.scss +4 -5
- package/src/styles/02-tools/_tools.background.scss +1 -13
- package/src/styles/02-tools/_tools.glass.scss +0 -1
- package/src/styles/02-tools/_tools.utility-api.scss +91 -48
- package/src/styles/03-generic/_generic.root.scss +1 -4
- package/src/styles/04-elements/_elements.body.scss +0 -1
- package/src/styles/06-components/_components.atomix-glass.scss +249 -0
- package/src/styles/06-components/_components.badge.scss +8 -23
- package/src/styles/06-components/_components.button.scss +8 -3
- package/src/styles/06-components/_components.callout.scss +10 -5
- package/src/styles/06-components/_components.card.scss +2 -14
- package/src/styles/06-components/_components.chart.scss +969 -1449
- package/src/styles/06-components/_components.dropdown.scss +19 -7
- package/src/styles/06-components/_components.edge-panel.scss +103 -0
- package/src/styles/06-components/_components.footer.scss +166 -85
- package/src/styles/06-components/_components.input.scss +8 -9
- package/src/styles/06-components/_components.list.scss +1 -0
- package/src/styles/06-components/_components.messages.scss +176 -0
- package/src/styles/06-components/_components.modal.scss +16 -4
- package/src/styles/06-components/_components.navbar.scss +12 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -0
- package/src/styles/06-components/_components.skeleton.scss +8 -6
- package/src/styles/06-components/_components.upload.scss +219 -4
- package/src/styles/06-components/old.chart.styles.scss +1 -30
- package/src/styles/99-utilities/_index.scss +1 -0
- package/src/styles/99-utilities/_utilities.glass-fixes.scss +1 -0
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/components/AtomixGlass/AtomixGlass.stories.tsx +0 -3011
- package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +0 -1369
- package/src/components/Chart/AdvancedChart.tsx +0 -624
- package/src/components/Chart/LineChartNew.tsx +0 -167
- package/src/components/Chart/RealTimeChart.tsx +0 -436
- package/src/components/DatePicker/DatePicker copy.tsx +0 -551
|
@@ -1,3011 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AtomixGlass.stories.tsx
|
|
3
|
-
*
|
|
4
|
-
* This file contains comprehensive Storybook stories for the AtomixGlass component, showcasing
|
|
5
|
-
* various use cases, configurations, and best practices. The stories demonstrate
|
|
6
|
-
* the component's versatility and provide examples for developers to reference.
|
|
7
|
-
*\
|
|
8
|
-
* @package Atomix
|
|
9
|
-
* @component AtomixGlass
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { Meta, StoryObj } from '@storybook/react';
|
|
13
|
-
import AtomixGlass from './AtomixGlass';
|
|
14
|
-
import Button from '../Button/Button';
|
|
15
|
-
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
16
|
-
import React from 'react';
|
|
17
|
-
import type { RefObject } from 'react';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Storybook meta configuration for AtomixGlass component
|
|
21
|
-
*
|
|
22
|
-
* This defines the component's metadata, documentation, and controls
|
|
23
|
-
* for the Storybook interface.
|
|
24
|
-
*/
|
|
25
|
-
const meta: Meta<typeof AtomixGlass> = {
|
|
26
|
-
title: 'Components/AtomixGlass',
|
|
27
|
-
component: AtomixGlass,
|
|
28
|
-
parameters: {
|
|
29
|
-
layout: 'centered',
|
|
30
|
-
docs: {
|
|
31
|
-
description: {
|
|
32
|
-
component:
|
|
33
|
-
'A glass-like component with chromatic aberration and displacement effects. The component provides a modern, frosted glass aesthetic with interactive hover effects. This component is ideal for creating modern UI elements with depth and visual interest.',
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
tags: ['autodocs'],
|
|
38
|
-
argTypes: {
|
|
39
|
-
children: {
|
|
40
|
-
control: 'text',
|
|
41
|
-
description: 'Content to display inside the glass effect',
|
|
42
|
-
},
|
|
43
|
-
displacementScale: {
|
|
44
|
-
control: { type: 'range', min: 0, max: 100, step: 1 },
|
|
45
|
-
description: 'Displacement scale for the glass effect (default: 70)',
|
|
46
|
-
table: { defaultValue: { summary: '70' } },
|
|
47
|
-
},
|
|
48
|
-
blurAmount: {
|
|
49
|
-
control: { type: 'range', min: 0, max: 10, step: 0.5 },
|
|
50
|
-
description: 'Blur amount for the backdrop (default: 0.0625)',
|
|
51
|
-
table: { defaultValue: { summary: '0.0625' } },
|
|
52
|
-
},
|
|
53
|
-
saturation: {
|
|
54
|
-
control: { type: 'range', min: 100, max: 300, step: 5 },
|
|
55
|
-
description: 'Saturation percentage for the backdrop (default: 140)',
|
|
56
|
-
table: { defaultValue: { summary: '140' } },
|
|
57
|
-
},
|
|
58
|
-
aberrationIntensity: {
|
|
59
|
-
control: { type: 'range', min: 0, max: 10, step: 0.1 },
|
|
60
|
-
description: 'Chromatic aberration intensity (default: 2)',
|
|
61
|
-
table: { defaultValue: { summary: '2' } },
|
|
62
|
-
},
|
|
63
|
-
elasticity: {
|
|
64
|
-
control: { type: 'range', min: 0, max: 1, step: 0.01 },
|
|
65
|
-
description: 'Elasticity factor for mouse interactions (default: 0.15)',
|
|
66
|
-
table: { defaultValue: { summary: '0.15' } },
|
|
67
|
-
},
|
|
68
|
-
cornerRadius: {
|
|
69
|
-
control: { type: 'range', min: 0, max: 50, step: 1 },
|
|
70
|
-
description: 'Corner radius in pixels (default: 20)',
|
|
71
|
-
table: { defaultValue: { summary: '20' } },
|
|
72
|
-
},
|
|
73
|
-
globalMousePos: {
|
|
74
|
-
control: 'object',
|
|
75
|
-
description: 'External global mouse position { x: number; y: number }',
|
|
76
|
-
},
|
|
77
|
-
mouseOffset: {
|
|
78
|
-
control: 'object',
|
|
79
|
-
description: 'External mouse offset { x: number; y: number }',
|
|
80
|
-
},
|
|
81
|
-
mouseContainer: {
|
|
82
|
-
control: false,
|
|
83
|
-
description: 'React ref object for mouse container element',
|
|
84
|
-
},
|
|
85
|
-
padding: {
|
|
86
|
-
control: 'text',
|
|
87
|
-
description: 'Padding for the glass container (default: "0 0")',
|
|
88
|
-
table: { defaultValue: { summary: '"0 0"' } },
|
|
89
|
-
},
|
|
90
|
-
overLight: {
|
|
91
|
-
control: 'boolean',
|
|
92
|
-
description: 'Whether the glass is over a light background (default: false)',
|
|
93
|
-
table: { defaultValue: { summary: 'false' } },
|
|
94
|
-
},
|
|
95
|
-
mode: {
|
|
96
|
-
control: 'select',
|
|
97
|
-
options: ['standard', 'polar', 'prominent', 'shader'],
|
|
98
|
-
description: 'Glass effect mode (default: "standard")',
|
|
99
|
-
table: { defaultValue: { summary: '"standard"' } },
|
|
100
|
-
},
|
|
101
|
-
onClick: {
|
|
102
|
-
action: 'clicked',
|
|
103
|
-
description: 'Click event handler',
|
|
104
|
-
},
|
|
105
|
-
className: {
|
|
106
|
-
control: 'text',
|
|
107
|
-
description: 'Additional CSS class names',
|
|
108
|
-
},
|
|
109
|
-
style: {
|
|
110
|
-
control: 'object',
|
|
111
|
-
description: 'CSS style object',
|
|
112
|
-
},
|
|
113
|
-
'aria-label': {
|
|
114
|
-
control: 'text',
|
|
115
|
-
description: 'ARIA label for accessibility',
|
|
116
|
-
},
|
|
117
|
-
'aria-describedby': {
|
|
118
|
-
control: 'text',
|
|
119
|
-
description: 'ARIA describedby attribute for accessibility',
|
|
120
|
-
},
|
|
121
|
-
role: {
|
|
122
|
-
control: 'text',
|
|
123
|
-
description: 'ARIA role attribute',
|
|
124
|
-
},
|
|
125
|
-
tabIndex: {
|
|
126
|
-
control: 'number',
|
|
127
|
-
description: 'Tab index for keyboard navigation',
|
|
128
|
-
},
|
|
129
|
-
reducedMotion: {
|
|
130
|
-
control: 'boolean',
|
|
131
|
-
description: 'Override for reduced motion preference (default: false)',
|
|
132
|
-
table: { defaultValue: { summary: 'false' } },
|
|
133
|
-
},
|
|
134
|
-
highContrast: {
|
|
135
|
-
control: 'boolean',
|
|
136
|
-
description: 'Override for high contrast preference (default: false)',
|
|
137
|
-
table: { defaultValue: { summary: 'false' } },
|
|
138
|
-
},
|
|
139
|
-
disableEffects: {
|
|
140
|
-
control: 'boolean',
|
|
141
|
-
description: 'Disable all visual effects (default: false)',
|
|
142
|
-
table: { defaultValue: { summary: 'false' } },
|
|
143
|
-
},
|
|
144
|
-
enablePerformanceMonitoring: {
|
|
145
|
-
control: 'boolean',
|
|
146
|
-
description: 'Enable performance monitoring (default: false)',
|
|
147
|
-
table: { defaultValue: { summary: 'false' } },
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
export default meta;
|
|
153
|
-
type Story = StoryObj<typeof AtomixGlass>;
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Enhanced BackgroundWrapper Component
|
|
157
|
-
*
|
|
158
|
-
* A utility component used throughout the stories to provide consistent background
|
|
159
|
-
* styling and overlay effects. This wrapper creates a visually appealing container
|
|
160
|
-
* for showcasing the AtomixGlass component in various scenarios.
|
|
161
|
-
*
|
|
162
|
-
* @component BackgroundWrapper
|
|
163
|
-
*/
|
|
164
|
-
interface BackgroundWrapperProps {
|
|
165
|
-
/** Child elements to render inside the wrapper */
|
|
166
|
-
children: React.ReactNode;
|
|
167
|
-
/** Background image URL or index from the backgroundImages array */
|
|
168
|
-
backgroundImage?: string;
|
|
169
|
-
/** Background index to use from the predefined array */
|
|
170
|
-
backgroundIndex?: number;
|
|
171
|
-
/** Optional overlay flag for quick overlay application */
|
|
172
|
-
overlay?: boolean;
|
|
173
|
-
/** Custom overlay color in CSS format */
|
|
174
|
-
overlayColor?: string;
|
|
175
|
-
/** Overlay opacity (0-1) */
|
|
176
|
-
overlayOpacity?: number;
|
|
177
|
-
/** Container height */
|
|
178
|
-
height?: string;
|
|
179
|
-
/** Container width */
|
|
180
|
-
width?: string;
|
|
181
|
-
/** Container border radius */
|
|
182
|
-
borderRadius?: string;
|
|
183
|
-
/** Container padding */
|
|
184
|
-
padding?: string;
|
|
185
|
-
/** Additional CSS class names */
|
|
186
|
-
className?: string;
|
|
187
|
-
/** Additional inline styles */
|
|
188
|
-
style?: React.CSSProperties;
|
|
189
|
-
/** Enable interactive background movement */
|
|
190
|
-
interactive?: boolean;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Interactive Story Container
|
|
195
|
-
*
|
|
196
|
-
* A container that provides mouse tracking and interactive background effects
|
|
197
|
-
* for enhanced storytelling and demonstration purposes.
|
|
198
|
-
*/
|
|
199
|
-
interface StoryContainerProps {
|
|
200
|
-
children: React.ReactNode;
|
|
201
|
-
style?: React.CSSProperties;
|
|
202
|
-
interactive?: boolean;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Interactive Wrapper Component
|
|
207
|
-
*
|
|
208
|
-
* Provides mouse position tracking and offset calculations for interactive stories
|
|
209
|
-
*/
|
|
210
|
-
interface InteractiveWrapperProps {
|
|
211
|
-
children: (
|
|
212
|
-
mousePos: { x: number; y: number },
|
|
213
|
-
mouseOffset: { x: number; y: number },
|
|
214
|
-
containerRef: RefObject<HTMLDivElement>
|
|
215
|
-
) => React.ReactNode;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* BackgroundWrapper Component Implementation
|
|
220
|
-
*
|
|
221
|
-
* Renders a container with a background image and optional overlay,
|
|
222
|
-
* providing a consistent environment for showcasing the AtomixGlass component.
|
|
223
|
-
*
|
|
224
|
-
* @param props - BackgroundWrapperProps
|
|
225
|
-
* @returns JSX.Element
|
|
226
|
-
*/
|
|
227
|
-
const BackgroundWrapper = ({
|
|
228
|
-
children,
|
|
229
|
-
backgroundImage,
|
|
230
|
-
backgroundIndex,
|
|
231
|
-
overlay = false,
|
|
232
|
-
overlayColor = 'rgba(0,0,0,0)',
|
|
233
|
-
overlayOpacity = 0,
|
|
234
|
-
height = '90vh',
|
|
235
|
-
width = '90vw',
|
|
236
|
-
borderRadius = '12px',
|
|
237
|
-
padding = '24px',
|
|
238
|
-
className = '',
|
|
239
|
-
style = {},
|
|
240
|
-
}: BackgroundWrapperProps) => {
|
|
241
|
-
// If backgroundIndex is provided, use it to select from the backgroundImages array
|
|
242
|
-
const bgImage =
|
|
243
|
-
backgroundIndex !== undefined ? backgroundImages[backgroundIndex] : backgroundImage;
|
|
244
|
-
|
|
245
|
-
// Apply default overlay settings if overlay flag is true
|
|
246
|
-
const finalOverlayColor = overlay ? 'rgba(0,0,0,0.5)' : overlayColor;
|
|
247
|
-
const finalOverlayOpacity = overlay ? 0.5 : overlayOpacity;
|
|
248
|
-
|
|
249
|
-
return (
|
|
250
|
-
<div
|
|
251
|
-
className={`atomix-glass-background ${className}`}
|
|
252
|
-
style={{
|
|
253
|
-
position: 'relative',
|
|
254
|
-
width: width,
|
|
255
|
-
minHeight: height,
|
|
256
|
-
height: '100%',
|
|
257
|
-
backgroundImage: bgImage ? `url(${bgImage})` : undefined,
|
|
258
|
-
backgroundColor: !bgImage ? '#1a1a2e' : undefined, // Fallback color if no image
|
|
259
|
-
backgroundSize: 'cover',
|
|
260
|
-
backgroundPosition: 'center',
|
|
261
|
-
backgroundAttachment: 'fixed',
|
|
262
|
-
display: 'flex',
|
|
263
|
-
alignItems: 'center',
|
|
264
|
-
justifyContent: 'center',
|
|
265
|
-
borderRadius: borderRadius,
|
|
266
|
-
padding: padding,
|
|
267
|
-
...style,
|
|
268
|
-
}}
|
|
269
|
-
>
|
|
270
|
-
{/* Overlay for better contrast and visual appeal */}
|
|
271
|
-
{finalOverlayOpacity > 0 && (
|
|
272
|
-
<div
|
|
273
|
-
style={{
|
|
274
|
-
position: 'absolute',
|
|
275
|
-
top: 0,
|
|
276
|
-
left: 0,
|
|
277
|
-
right: 0,
|
|
278
|
-
bottom: 0,
|
|
279
|
-
backgroundColor: finalOverlayColor,
|
|
280
|
-
opacity: finalOverlayOpacity,
|
|
281
|
-
zIndex: -1,
|
|
282
|
-
}}
|
|
283
|
-
/>
|
|
284
|
-
)}
|
|
285
|
-
<div
|
|
286
|
-
style={{
|
|
287
|
-
position: 'relative',
|
|
288
|
-
width: '100%',
|
|
289
|
-
height: '100%',
|
|
290
|
-
display: 'flex',
|
|
291
|
-
alignItems: 'center',
|
|
292
|
-
justifyContent: 'center',
|
|
293
|
-
}}
|
|
294
|
-
>
|
|
295
|
-
{children}
|
|
296
|
-
</div>
|
|
297
|
-
</div>
|
|
298
|
-
);
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Interactive Story Container Component
|
|
303
|
-
*
|
|
304
|
-
* A container that provides mouse tracking and interactive background effects
|
|
305
|
-
* for enhanced storytelling and demonstration purposes.
|
|
306
|
-
*/
|
|
307
|
-
const StoryContainer = ({ children, style = {}, interactive = false }: StoryContainerProps) => {
|
|
308
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
309
|
-
const [backgroundPosition, setBackgroundPosition] = useState({ x: 0, y: 0 });
|
|
310
|
-
|
|
311
|
-
const handleMouseMove = useCallback(
|
|
312
|
-
(e: MouseEvent) => {
|
|
313
|
-
if (containerRef.current && interactive) {
|
|
314
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
315
|
-
const centerX = rect.left + rect.width / 2;
|
|
316
|
-
const centerY = rect.top + rect.height / 2;
|
|
317
|
-
|
|
318
|
-
// Calculate offset as a percentage
|
|
319
|
-
const offsetX = ((e.clientX - centerX) / rect.width) * 100;
|
|
320
|
-
const offsetY = ((e.clientY - centerY) / rect.height) * 100;
|
|
321
|
-
|
|
322
|
-
setBackgroundPosition({ x: offsetX, y: offsetY });
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
[interactive]
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
useEffect(() => {
|
|
329
|
-
const currentRef = containerRef.current;
|
|
330
|
-
if (currentRef && interactive) {
|
|
331
|
-
currentRef.addEventListener('mousemove', handleMouseMove);
|
|
332
|
-
return () => {
|
|
333
|
-
currentRef.removeEventListener('mousemove', handleMouseMove);
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
}, [handleMouseMove, interactive]);
|
|
337
|
-
|
|
338
|
-
return (
|
|
339
|
-
<div
|
|
340
|
-
ref={containerRef}
|
|
341
|
-
style={{
|
|
342
|
-
width: '100vw',
|
|
343
|
-
height: '100vh',
|
|
344
|
-
display: 'flex',
|
|
345
|
-
alignItems: 'center',
|
|
346
|
-
justifyContent: 'center',
|
|
347
|
-
backgroundImage: interactive
|
|
348
|
-
? 'url(https://images.unsplash.com/photo-1497366216548-37526070297c?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)'
|
|
349
|
-
: undefined,
|
|
350
|
-
backgroundSize: interactive ? '160%' : 'cover',
|
|
351
|
-
backgroundPosition: interactive
|
|
352
|
-
? `calc(50% + ${backgroundPosition.x}px) calc(50% + ${backgroundPosition.y}px)`
|
|
353
|
-
: 'center',
|
|
354
|
-
...style,
|
|
355
|
-
}}
|
|
356
|
-
>
|
|
357
|
-
{children}
|
|
358
|
-
</div>
|
|
359
|
-
);
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Interactive Wrapper Component
|
|
364
|
-
*
|
|
365
|
-
* Provides mouse position tracking and offset calculations for interactive stories
|
|
366
|
-
*/
|
|
367
|
-
const InteractiveWrapper = ({ children }: InteractiveWrapperProps) => {
|
|
368
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
369
|
-
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
|
|
370
|
-
const [mouseOffset, setMouseOffset] = useState({ x: 0, y: 0 });
|
|
371
|
-
|
|
372
|
-
const handleMouseMove = useCallback((e: MouseEvent) => {
|
|
373
|
-
if (containerRef.current) {
|
|
374
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
375
|
-
const centerX = rect.left + rect.width / 2;
|
|
376
|
-
const centerY = rect.top + rect.height / 2;
|
|
377
|
-
|
|
378
|
-
setMouseOffset({
|
|
379
|
-
x: ((e.clientX - centerX) / rect.width) * 100,
|
|
380
|
-
y: ((e.clientY - centerY) / rect.height) * 100,
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
setMousePos({ x: e.clientX, y: e.clientY });
|
|
384
|
-
}, []);
|
|
385
|
-
|
|
386
|
-
useEffect(() => {
|
|
387
|
-
const currentRef = containerRef.current;
|
|
388
|
-
currentRef?.addEventListener('mousemove', handleMouseMove);
|
|
389
|
-
return () => {
|
|
390
|
-
currentRef?.removeEventListener('mousemove', handleMouseMove);
|
|
391
|
-
};
|
|
392
|
-
}, [handleMouseMove]);
|
|
393
|
-
|
|
394
|
-
return (
|
|
395
|
-
<div ref={containerRef} style={{ width: '100%', height: '100%' }}>
|
|
396
|
-
{children(mousePos, mouseOffset, containerRef)}
|
|
397
|
-
</div>
|
|
398
|
-
);
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Collection of high-quality background images for different moods and scenarios
|
|
403
|
-
*
|
|
404
|
-
* This array provides a variety of background options that work well with the
|
|
405
|
-
* AtomixGlass component, showcasing different visual styles and contexts.
|
|
406
|
-
*/
|
|
407
|
-
const backgroundImages = [
|
|
408
|
-
// 0: Modern office interior with natural lighting
|
|
409
|
-
'https://images.pexels.com/photos/5653101/pexels-photo-5653101.jpeg',
|
|
410
|
-
// 1: Beautiful natural landscape - mountains and lake
|
|
411
|
-
'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
412
|
-
// 2: Urban cityscape with modern buildings
|
|
413
|
-
'https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
414
|
-
// 3: Forest path with sunlight filtering through trees
|
|
415
|
-
'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
416
|
-
// 4: Ocean waves and beach scene
|
|
417
|
-
'https://images.unsplash.com/photo-1505142468610-359e7d316be0?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
418
|
-
// 5: Modern architecture with glass facades
|
|
419
|
-
'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
420
|
-
// 6: Cozy café interior with warm lighting
|
|
421
|
-
'https://images.unsplash.com/photo-1554118811-1e0d58224f24?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
422
|
-
// 7: Desert landscape with dramatic sky
|
|
423
|
-
'https://images.unsplash.com/photo-1509316785289-025f5b846b35?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
424
|
-
// 8: Tropical paradise with palm trees and ocean
|
|
425
|
-
'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
426
|
-
// 9: Modern library or workspace with natural light
|
|
427
|
-
'https://images.unsplash.com/photo-1521587760476-6c12a4b040da?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
428
|
-
];
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Legacy backgrounds object for backward compatibility
|
|
432
|
-
* @deprecated Use backgroundImages array instead
|
|
433
|
-
*/
|
|
434
|
-
const backgrounds = {
|
|
435
|
-
// Office and workspace environments
|
|
436
|
-
blueGradient: backgroundImages[0], // Modern office interior
|
|
437
|
-
purpleGradient: backgroundImages[1], // Mountain landscape
|
|
438
|
-
greenGradient: backgroundImages[3], // Forest path
|
|
439
|
-
|
|
440
|
-
// Apple-inspired natural scenes
|
|
441
|
-
macosWallpaper: backgroundImages[1], // Mountain landscape
|
|
442
|
-
iosWallpaper: backgroundImages[4], // Ocean waves
|
|
443
|
-
|
|
444
|
-
// Nature scenes
|
|
445
|
-
mountains: backgroundImages[1], // Mountain landscape
|
|
446
|
-
ocean: backgroundImages[4], // Ocean waves
|
|
447
|
-
|
|
448
|
-
// Urban environments
|
|
449
|
-
cityNight: backgroundImages[2], // Urban cityscape
|
|
450
|
-
cityDay: backgroundImages[5], // Modern architecture
|
|
451
|
-
|
|
452
|
-
// Interior spaces
|
|
453
|
-
abstract1: backgroundImages[6], // Cozy café interior
|
|
454
|
-
abstract2: backgroundImages[9], // Modern library
|
|
455
|
-
|
|
456
|
-
// Video backgrounds
|
|
457
|
-
videoBackground:
|
|
458
|
-
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Default showcase of the AtomixGlass component
|
|
463
|
-
*
|
|
464
|
-
* This story demonstrates the default configuration of the AtomixGlass component
|
|
465
|
-
* with carefully selected parameters to achieve an optimal glass effect. It serves
|
|
466
|
-
* as a reference implementation with balanced settings suitable for most use cases.
|
|
467
|
-
*
|
|
468
|
-
* Key features demonstrated:
|
|
469
|
-
* - Balanced displacement scale for subtle distortion
|
|
470
|
-
* - Moderate blur amount for the frosted glass effect
|
|
471
|
-
* - Enhanced saturation for visual appeal
|
|
472
|
-
* - Subtle chromatic aberration for depth
|
|
473
|
-
* - Interactive hover effects for engagement
|
|
474
|
-
*/
|
|
475
|
-
export const Default: Story = {
|
|
476
|
-
args: {
|
|
477
|
-
children: (
|
|
478
|
-
<div style={{ padding: '30px', textAlign: 'center', maxWidth: '400px' }}>
|
|
479
|
-
<h2 style={{ margin: '0 0 16px 0', fontSize: '24px', fontWeight: 600 }}>AtomixGlass</h2>
|
|
480
|
-
<p style={{ margin: '0 0 20px 0', fontSize: '16px', lineHeight: 1.6 }}>
|
|
481
|
-
A premium glass morphism component with realistic light refraction, chromatic aberration,
|
|
482
|
-
and interactive effects.
|
|
483
|
-
</p>
|
|
484
|
-
<div style={{ display: 'flex', justifyContent: 'center', gap: '12px', flexWrap: 'wrap' }}>
|
|
485
|
-
<button className="c-btn c-btn--primary">Explore</button>
|
|
486
|
-
<button className="c-btn c-btn--outline-light">Learn More</button>
|
|
487
|
-
</div>
|
|
488
|
-
</div>
|
|
489
|
-
),
|
|
490
|
-
displacementScale: 15, // Using component default
|
|
491
|
-
blurAmount: 1, // Using component default
|
|
492
|
-
saturation: 140, // Using component default
|
|
493
|
-
aberrationIntensity: 2, // Using component default
|
|
494
|
-
elasticity: 0.15, // Using component default
|
|
495
|
-
cornerRadius: 20, // Using component default
|
|
496
|
-
padding: '0 0', // Using component default
|
|
497
|
-
overLight: false, // Using component default
|
|
498
|
-
mode: 'standard', // Using component default
|
|
499
|
-
},
|
|
500
|
-
decorators: [
|
|
501
|
-
Story => (
|
|
502
|
-
<BackgroundWrapper
|
|
503
|
-
backgroundImage={backgrounds.blueGradient}
|
|
504
|
-
height="70vh"
|
|
505
|
-
width="90vw"
|
|
506
|
-
overlayOpacity={0.1}
|
|
507
|
-
overlayColor="rgba(0,0,0,0.2)"
|
|
508
|
-
>
|
|
509
|
-
<Story />
|
|
510
|
-
</BackgroundWrapper>
|
|
511
|
-
),
|
|
512
|
-
],
|
|
513
|
-
parameters: {
|
|
514
|
-
docs: {
|
|
515
|
-
description: {
|
|
516
|
-
story:
|
|
517
|
-
'The default configuration of AtomixGlass with optimal parameters for a realistic glass effect. This component mimics the Apple-style liquid glass UI with chromatic aberration and displacement effects.',
|
|
518
|
-
},
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
// Interactive demo with controls
|
|
524
|
-
export const Interactive: Story = {
|
|
525
|
-
render: args => {
|
|
526
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
527
|
-
const [isActive, setIsActive] = useState(false);
|
|
528
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
529
|
-
const [isClicked, setIsClicked] = useState(false);
|
|
530
|
-
|
|
531
|
-
return (
|
|
532
|
-
<BackgroundWrapper
|
|
533
|
-
backgroundImage={backgrounds.purpleGradient}
|
|
534
|
-
height="65vh"
|
|
535
|
-
overlayOpacity={0.15}
|
|
536
|
-
>
|
|
537
|
-
<AtomixGlass
|
|
538
|
-
{...args}
|
|
539
|
-
onClick={() => {
|
|
540
|
-
setIsActive(!isActive);
|
|
541
|
-
setIsClicked(!isClicked);
|
|
542
|
-
}}
|
|
543
|
-
>
|
|
544
|
-
<div style={{ padding: '30px', textAlign: 'center', minWidth: '300px' }}>
|
|
545
|
-
<h3 style={{ margin: '0 0 16px 0', fontSize: '22px', fontWeight: 500 }}>
|
|
546
|
-
Interactive Glass
|
|
547
|
-
</h3>
|
|
548
|
-
<p style={{ margin: '0 0 20px 0', fontSize: '16px', lineHeight: 1.5 }}>
|
|
549
|
-
{isClicked
|
|
550
|
-
? 'Thanks for clicking!'
|
|
551
|
-
: 'Hover and click to see the interactive effects in action.'}
|
|
552
|
-
</p>
|
|
553
|
-
<button
|
|
554
|
-
className={`c-btn c-btn--${isClicked ? 'success' : 'primary'}`}
|
|
555
|
-
style={{ transition: 'all 0.3s ease' }}
|
|
556
|
-
>
|
|
557
|
-
{isClicked ? 'Clicked!' : 'Click Me'}
|
|
558
|
-
</button>
|
|
559
|
-
</div>
|
|
560
|
-
</AtomixGlass>
|
|
561
|
-
</BackgroundWrapper>
|
|
562
|
-
);
|
|
563
|
-
},
|
|
564
|
-
args: {
|
|
565
|
-
displacementScale: 15,
|
|
566
|
-
blurAmount: 0.0625,
|
|
567
|
-
saturation: 200,
|
|
568
|
-
aberrationIntensity: 3,
|
|
569
|
-
elasticity: 0.2,
|
|
570
|
-
cornerRadius: 15,
|
|
571
|
-
padding: '0 0',
|
|
572
|
-
overLight: false,
|
|
573
|
-
mode: 'standard',
|
|
574
|
-
},
|
|
575
|
-
parameters: {
|
|
576
|
-
docs: {
|
|
577
|
-
description: {
|
|
578
|
-
story:
|
|
579
|
-
'An interactive example that demonstrates the hover and click effects of the AtomixGlass component. Try hovering and clicking to see the glass react to user interactions.',
|
|
580
|
-
},
|
|
581
|
-
},
|
|
582
|
-
},
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
/**
|
|
586
|
-
* Mode Showcase - Demonstrates the visual differences between the various modes
|
|
587
|
-
*
|
|
588
|
-
* This story showcases all available modes of the AtomixGlass component with
|
|
589
|
-
* optimized settings for each mode to highlight their unique characteristics.
|
|
590
|
-
*/
|
|
591
|
-
/**
|
|
592
|
-
* ModeShowcase Story
|
|
593
|
-
*
|
|
594
|
-
* This story demonstrates the different modes available in the AtomixGlass component.
|
|
595
|
-
* Each mode provides a unique visual effect with different displacement patterns,
|
|
596
|
-
* blur amounts, and aberration intensities. This showcase allows users to compare
|
|
597
|
-
* the different modes side by side and understand their visual characteristics.
|
|
598
|
-
*
|
|
599
|
-
* Modes demonstrated:
|
|
600
|
-
* - standard: Balanced displacement and aberration
|
|
601
|
-
* - polar: Circular refraction pattern
|
|
602
|
-
* - prominent: Enhanced displacement with stronger edge effects
|
|
603
|
-
* - shader: Advanced shader-based displacement for maximum visual impact
|
|
604
|
-
*/
|
|
605
|
-
export const ModeShowcase: Story = {
|
|
606
|
-
parameters: {
|
|
607
|
-
docs: {
|
|
608
|
-
description: {
|
|
609
|
-
story:
|
|
610
|
-
'Showcases the different modes available in the AtomixGlass component, highlighting their unique visual characteristics.',
|
|
611
|
-
},
|
|
612
|
-
},
|
|
613
|
-
},
|
|
614
|
-
render: () => {
|
|
615
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
616
|
-
const [activeMode, setActiveMode] = useState<string | null>(null);
|
|
617
|
-
const modes = ['standard', 'polar', 'prominent', 'shader'] as const;
|
|
618
|
-
|
|
619
|
-
// Different settings for each mode to highlight their unique characteristics
|
|
620
|
-
const modeSettings = {
|
|
621
|
-
standard: {
|
|
622
|
-
displacementScale: 15,
|
|
623
|
-
blurAmount: 0.0625,
|
|
624
|
-
saturation: 140,
|
|
625
|
-
aberrationIntensity: 2,
|
|
626
|
-
description: 'Standard glass effect with balanced displacement and aberration',
|
|
627
|
-
color: '#ffffff',
|
|
628
|
-
},
|
|
629
|
-
polar: {
|
|
630
|
-
displacementScale: 15,
|
|
631
|
-
blurAmount: 0.05,
|
|
632
|
-
saturation: 160,
|
|
633
|
-
aberrationIntensity: 2.5,
|
|
634
|
-
description: 'Polar displacement creates a circular refraction pattern',
|
|
635
|
-
color: '#f0f8ff',
|
|
636
|
-
},
|
|
637
|
-
prominent: {
|
|
638
|
-
displacementScale: 15,
|
|
639
|
-
blurAmount: 0.08,
|
|
640
|
-
saturation: 180,
|
|
641
|
-
aberrationIntensity: 3,
|
|
642
|
-
description: 'Enhanced displacement with stronger edge effects',
|
|
643
|
-
color: '#ffffff',
|
|
644
|
-
},
|
|
645
|
-
shader: {
|
|
646
|
-
displacementScale: 15,
|
|
647
|
-
blurAmount: 0.1,
|
|
648
|
-
saturation: 150,
|
|
649
|
-
aberrationIntensity: 4,
|
|
650
|
-
description: 'Advanced shader-based displacement for maximum visual impact',
|
|
651
|
-
color: '#e6f7ff',
|
|
652
|
-
},
|
|
653
|
-
};
|
|
654
|
-
|
|
655
|
-
// Handle mouse enter/leave for cards
|
|
656
|
-
const handleMouseEnter = (mode: string) => {
|
|
657
|
-
setActiveMode(mode);
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
const handleMouseLeave = () => {
|
|
661
|
-
setActiveMode(null);
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
return (
|
|
665
|
-
<BackgroundWrapper backgroundImage={backgroundImages[2]} height="75vh" overlayOpacity={0.1}>
|
|
666
|
-
<div>
|
|
667
|
-
<div
|
|
668
|
-
style={{
|
|
669
|
-
padding: '20px 0',
|
|
670
|
-
textAlign: 'center',
|
|
671
|
-
marginBottom: '20px',
|
|
672
|
-
}}
|
|
673
|
-
>
|
|
674
|
-
<h2
|
|
675
|
-
style={{
|
|
676
|
-
margin: '0 0 10px 0',
|
|
677
|
-
fontSize: '32px',
|
|
678
|
-
fontWeight: 500,
|
|
679
|
-
color: '#ffffff',
|
|
680
|
-
textShadow: '0 2px 4px rgba(0,0,0,0.2)',
|
|
681
|
-
}}
|
|
682
|
-
>
|
|
683
|
-
AtomixGlass Modes
|
|
684
|
-
</h2>
|
|
685
|
-
<p
|
|
686
|
-
style={{
|
|
687
|
-
fontSize: '16px',
|
|
688
|
-
maxWidth: '500px',
|
|
689
|
-
margin: '0 auto',
|
|
690
|
-
color: '#ffffff',
|
|
691
|
-
textShadow: '0 1px 2px rgba(0,0,0,0.2)',
|
|
692
|
-
}}
|
|
693
|
-
>
|
|
694
|
-
Hover over each card to see how different modes affect the appearance and behavior of
|
|
695
|
-
the glass effect.
|
|
696
|
-
</p>
|
|
697
|
-
</div>
|
|
698
|
-
|
|
699
|
-
<div
|
|
700
|
-
style={{
|
|
701
|
-
display: 'flex',
|
|
702
|
-
flexWrap: 'wrap',
|
|
703
|
-
justifyContent: 'center',
|
|
704
|
-
alignContent: 'center',
|
|
705
|
-
gap: '24px',
|
|
706
|
-
width: '70vw',
|
|
707
|
-
}}
|
|
708
|
-
>
|
|
709
|
-
{modes.map(mode => {
|
|
710
|
-
const settings = modeSettings[mode];
|
|
711
|
-
const isActive = activeMode === mode;
|
|
712
|
-
|
|
713
|
-
return (
|
|
714
|
-
<AtomixGlass
|
|
715
|
-
key={mode}
|
|
716
|
-
mode={mode}
|
|
717
|
-
displacementScale={settings.displacementScale}
|
|
718
|
-
blurAmount={settings.blurAmount}
|
|
719
|
-
saturation={settings.saturation}
|
|
720
|
-
aberrationIntensity={settings.aberrationIntensity}
|
|
721
|
-
elasticity={0.15}
|
|
722
|
-
cornerRadius={50}
|
|
723
|
-
onClick={() => handleMouseEnter(mode)}
|
|
724
|
-
>
|
|
725
|
-
<div
|
|
726
|
-
style={{
|
|
727
|
-
padding: '24px 50px',
|
|
728
|
-
textAlign: 'center',
|
|
729
|
-
maxWidth: '400px',
|
|
730
|
-
minHeight: '200px',
|
|
731
|
-
width: '100%',
|
|
732
|
-
}}
|
|
733
|
-
>
|
|
734
|
-
<h3
|
|
735
|
-
style={{
|
|
736
|
-
margin: '0 0 12px 0',
|
|
737
|
-
fontSize: '20px',
|
|
738
|
-
fontWeight: 500,
|
|
739
|
-
color: settings.color,
|
|
740
|
-
}}
|
|
741
|
-
>
|
|
742
|
-
{mode.charAt(0).toUpperCase() + mode.slice(1)} Mode
|
|
743
|
-
</h3>
|
|
744
|
-
<p
|
|
745
|
-
style={{
|
|
746
|
-
margin: '0 0 16px 0',
|
|
747
|
-
fontSize: '14px',
|
|
748
|
-
lineHeight: 1.5,
|
|
749
|
-
color: settings.color,
|
|
750
|
-
}}
|
|
751
|
-
>
|
|
752
|
-
{settings.description}
|
|
753
|
-
</p>
|
|
754
|
-
<div
|
|
755
|
-
style={{
|
|
756
|
-
display: 'flex',
|
|
757
|
-
justifyContent: 'center',
|
|
758
|
-
alignItems: 'center',
|
|
759
|
-
gap: '8px',
|
|
760
|
-
marginTop: '12px',
|
|
761
|
-
flexWrap: 'wrap',
|
|
762
|
-
}}
|
|
763
|
-
>
|
|
764
|
-
<span
|
|
765
|
-
style={{
|
|
766
|
-
fontSize: '12px',
|
|
767
|
-
padding: '4px 8px',
|
|
768
|
-
borderRadius: '4px',
|
|
769
|
-
background: 'rgba(255,255,255,0.2)',
|
|
770
|
-
}}
|
|
771
|
-
>
|
|
772
|
-
Displacement: {settings.displacementScale}
|
|
773
|
-
</span>
|
|
774
|
-
<span
|
|
775
|
-
style={{
|
|
776
|
-
fontSize: '12px',
|
|
777
|
-
padding: '4px 8px',
|
|
778
|
-
borderRadius: '4px',
|
|
779
|
-
background: 'rgba(255,255,255,0.2)',
|
|
780
|
-
}}
|
|
781
|
-
>
|
|
782
|
-
Blur: {settings.blurAmount}
|
|
783
|
-
</span>
|
|
784
|
-
<span
|
|
785
|
-
style={{
|
|
786
|
-
fontSize: '12px',
|
|
787
|
-
padding: '4px 8px',
|
|
788
|
-
borderRadius: '4px',
|
|
789
|
-
background: 'rgba(255,255,255,0.2)',
|
|
790
|
-
}}
|
|
791
|
-
>
|
|
792
|
-
Aberration: {settings.aberrationIntensity}
|
|
793
|
-
</span>
|
|
794
|
-
</div>
|
|
795
|
-
</div>
|
|
796
|
-
</AtomixGlass>
|
|
797
|
-
);
|
|
798
|
-
})}
|
|
799
|
-
</div>
|
|
800
|
-
</div>
|
|
801
|
-
</BackgroundWrapper>
|
|
802
|
-
);
|
|
803
|
-
},
|
|
804
|
-
};
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Apple-inspired UI example showcasing the liquid glass effect
|
|
808
|
-
*
|
|
809
|
-
* This story demonstrates how to create Apple-like interfaces using the AtomixGlass component,
|
|
810
|
-
* mimicking the frosted glass effect seen in macOS and iOS with realistic design elements
|
|
811
|
-
* and interactions that closely resemble Apple's design language.
|
|
812
|
-
*/
|
|
813
|
-
export const AppleInspiredUI: Story = {
|
|
814
|
-
render: () => {
|
|
815
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
816
|
-
const [activeTab, setActiveTab] = useState('home');
|
|
817
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
818
|
-
const [currentTime, setCurrentTime] = useState('');
|
|
819
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
820
|
-
const [hoverDockItem, setHoverDockItem] = useState<number | null>(null);
|
|
821
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
822
|
-
const [notificationCount, setNotificationCount] = useState(3);
|
|
823
|
-
|
|
824
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
825
|
-
useEffect(() => {
|
|
826
|
-
// Update time every minute
|
|
827
|
-
const updateTime = () => {
|
|
828
|
-
const now = new Date();
|
|
829
|
-
const hours = now.getHours();
|
|
830
|
-
const minutes = now.getMinutes();
|
|
831
|
-
const ampm = hours >= 12 ? 'PM' : 'AM';
|
|
832
|
-
const formattedHours = hours % 12 || 12;
|
|
833
|
-
const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes;
|
|
834
|
-
setCurrentTime(`${formattedHours}:${formattedMinutes} ${ampm}`);
|
|
835
|
-
};
|
|
836
|
-
|
|
837
|
-
updateTime(); // Initial call
|
|
838
|
-
const interval = setInterval(updateTime, 60000);
|
|
839
|
-
|
|
840
|
-
return () => clearInterval(interval);
|
|
841
|
-
}, []);
|
|
842
|
-
|
|
843
|
-
const handleTabChange = (tab: string) => {
|
|
844
|
-
setActiveTab(tab);
|
|
845
|
-
};
|
|
846
|
-
|
|
847
|
-
// Apple-style app icons with gradient backgrounds
|
|
848
|
-
const appIcons = [
|
|
849
|
-
{ name: 'Photos', color: 'linear-gradient(135deg, #FF9500, #FF2D55)', symbol: '📷' },
|
|
850
|
-
{ name: 'Music', color: 'linear-gradient(135deg, #FF2D55, #AF52DE)', symbol: '🎵' },
|
|
851
|
-
{ name: 'Mail', color: 'linear-gradient(135deg, #5AC8FA, #007AFF)', symbol: '✉️' },
|
|
852
|
-
{ name: 'Maps', color: 'linear-gradient(135deg, #34C759, #5AC8FA)', symbol: '🗺️' },
|
|
853
|
-
{ name: 'Weather', color: 'linear-gradient(135deg, #007AFF, #5AC8FA)', symbol: '☀️' },
|
|
854
|
-
{ name: 'Notes', color: 'linear-gradient(135deg, #FFCC00, #FF9500)', symbol: '📝' },
|
|
855
|
-
];
|
|
856
|
-
|
|
857
|
-
// Dock apps with more realistic icons
|
|
858
|
-
const dockApps = [
|
|
859
|
-
{ name: 'Finder', symbol: '🔍', color: 'linear-gradient(135deg, #1E88E5, #64B5F6)' },
|
|
860
|
-
{ name: 'Safari', symbol: '🧭', color: 'linear-gradient(135deg, #039BE5, #81D4FA)' },
|
|
861
|
-
{ name: 'Messages', symbol: '💬', color: 'linear-gradient(135deg, #43A047, #81C784)' },
|
|
862
|
-
{ name: 'Calendar', symbol: '📅', color: 'linear-gradient(135deg, #E53935, #EF5350)' },
|
|
863
|
-
{ name: 'Photos', symbol: '🖼️', color: 'linear-gradient(135deg, #8E24AA, #BA68C8)' },
|
|
864
|
-
];
|
|
865
|
-
|
|
866
|
-
return (
|
|
867
|
-
<BackgroundWrapper
|
|
868
|
-
backgroundImage={'https://images.pexels.com/photos/18772443/pexels-photo-18772443.jpeg'}
|
|
869
|
-
height="90vh"
|
|
870
|
-
style={{ maxWidth: '90vw', padding: '10px' }}
|
|
871
|
-
>
|
|
872
|
-
{/* Main content area */}
|
|
873
|
-
<div
|
|
874
|
-
style={{
|
|
875
|
-
display: 'flex',
|
|
876
|
-
flexDirection: 'column',
|
|
877
|
-
alignItems: 'center',
|
|
878
|
-
justifyContent: 'space-between',
|
|
879
|
-
height: '90vh',
|
|
880
|
-
width: '100%',
|
|
881
|
-
}}
|
|
882
|
-
>
|
|
883
|
-
{/* Top menu bar - macOS style with improved design */}
|
|
884
|
-
|
|
885
|
-
<AtomixGlass
|
|
886
|
-
displacementScale={15}
|
|
887
|
-
blurAmount={2}
|
|
888
|
-
saturation={150}
|
|
889
|
-
aberrationIntensity={0.2}
|
|
890
|
-
cornerRadius={8}
|
|
891
|
-
mode="shader"
|
|
892
|
-
elasticity={0}
|
|
893
|
-
>
|
|
894
|
-
<div
|
|
895
|
-
style={{
|
|
896
|
-
padding: '10px 16px',
|
|
897
|
-
display: 'flex',
|
|
898
|
-
justifyContent: 'space-between',
|
|
899
|
-
alignItems: 'center',
|
|
900
|
-
width: '77vw',
|
|
901
|
-
}}
|
|
902
|
-
>
|
|
903
|
-
{/* Apple logo and app menu */}
|
|
904
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '20px' }}>
|
|
905
|
-
<span
|
|
906
|
-
style={{
|
|
907
|
-
fontSize: '20px',
|
|
908
|
-
fontWeight: 600,
|
|
909
|
-
display: 'flex',
|
|
910
|
-
alignItems: 'center',
|
|
911
|
-
gap: '6px',
|
|
912
|
-
}}
|
|
913
|
-
>
|
|
914
|
-
<span style={{ fontSize: '22px' }}>🍎</span>
|
|
915
|
-
<span>Atomix</span>
|
|
916
|
-
</span>
|
|
917
|
-
<div style={{ display: 'flex', gap: '16px' }}>
|
|
918
|
-
{['Finder', 'File', 'Edit', 'View', 'Window', 'Help'].map(tab => (
|
|
919
|
-
<button
|
|
920
|
-
key={tab}
|
|
921
|
-
onClick={() => handleTabChange(tab.toLowerCase())}
|
|
922
|
-
style={{
|
|
923
|
-
background: 'none',
|
|
924
|
-
border: 'none',
|
|
925
|
-
padding: '4px 8px',
|
|
926
|
-
borderRadius: '4px',
|
|
927
|
-
cursor: 'pointer',
|
|
928
|
-
backgroundColor:
|
|
929
|
-
activeTab === tab.toLowerCase()
|
|
930
|
-
? 'rgba(255,255,255,0.15)'
|
|
931
|
-
: 'transparent',
|
|
932
|
-
transition: 'all 0.2s ease',
|
|
933
|
-
fontSize: '13px',
|
|
934
|
-
fontWeight: activeTab === tab.toLowerCase() ? 600 : 400,
|
|
935
|
-
color: 'inherit',
|
|
936
|
-
}}
|
|
937
|
-
>
|
|
938
|
-
{tab}
|
|
939
|
-
</button>
|
|
940
|
-
))}
|
|
941
|
-
</div>
|
|
942
|
-
</div>
|
|
943
|
-
|
|
944
|
-
{/* Status icons */}
|
|
945
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
|
|
946
|
-
{/* Battery indicator */}
|
|
947
|
-
<div
|
|
948
|
-
style={{
|
|
949
|
-
display: 'flex',
|
|
950
|
-
alignItems: 'center',
|
|
951
|
-
fontSize: '12px',
|
|
952
|
-
gap: '4px',
|
|
953
|
-
}}
|
|
954
|
-
>
|
|
955
|
-
<span
|
|
956
|
-
style={{
|
|
957
|
-
display: 'inline-block',
|
|
958
|
-
width: '20px',
|
|
959
|
-
height: '10px',
|
|
960
|
-
border: '1px solid currentColor',
|
|
961
|
-
borderRadius: '2px',
|
|
962
|
-
position: 'relative',
|
|
963
|
-
marginRight: '2px',
|
|
964
|
-
}}
|
|
965
|
-
>
|
|
966
|
-
<span
|
|
967
|
-
style={{
|
|
968
|
-
position: 'absolute',
|
|
969
|
-
left: '1px',
|
|
970
|
-
top: '1px',
|
|
971
|
-
bottom: '1px',
|
|
972
|
-
width: '12px',
|
|
973
|
-
backgroundColor: 'currentColor',
|
|
974
|
-
borderRadius: '1px',
|
|
975
|
-
}}
|
|
976
|
-
></span>
|
|
977
|
-
<span
|
|
978
|
-
style={{
|
|
979
|
-
position: 'absolute',
|
|
980
|
-
right: '-4px',
|
|
981
|
-
top: '2px',
|
|
982
|
-
width: '2px',
|
|
983
|
-
height: '6px',
|
|
984
|
-
backgroundColor: 'currentColor',
|
|
985
|
-
borderRadius: '0 1px 1px 0',
|
|
986
|
-
}}
|
|
987
|
-
></span>
|
|
988
|
-
</span>
|
|
989
|
-
<span>75%</span>
|
|
990
|
-
</div>
|
|
991
|
-
|
|
992
|
-
{/* WiFi icon */}
|
|
993
|
-
<div style={{ fontSize: '14px' }}>📶</div>
|
|
994
|
-
|
|
995
|
-
{/* Time */}
|
|
996
|
-
<span style={{ fontSize: '13px', fontWeight: 500 }}>
|
|
997
|
-
{currentTime || '10:30 AM'}
|
|
998
|
-
</span>
|
|
999
|
-
|
|
1000
|
-
{/* User profile */}
|
|
1001
|
-
<div
|
|
1002
|
-
style={{
|
|
1003
|
-
position: 'relative',
|
|
1004
|
-
width: '26px',
|
|
1005
|
-
height: '26px',
|
|
1006
|
-
borderRadius: '50%',
|
|
1007
|
-
background: 'linear-gradient(135deg, #64B5F6, #1976D2)',
|
|
1008
|
-
display: 'flex',
|
|
1009
|
-
alignItems: 'center',
|
|
1010
|
-
justifyContent: 'center',
|
|
1011
|
-
fontSize: '12px',
|
|
1012
|
-
fontWeight: 600,
|
|
1013
|
-
color: 'white',
|
|
1014
|
-
cursor: 'pointer',
|
|
1015
|
-
boxShadow: '0 2px 5px rgba(0,0,0,0.2)',
|
|
1016
|
-
}}
|
|
1017
|
-
>
|
|
1018
|
-
A
|
|
1019
|
-
{notificationCount > 0 && (
|
|
1020
|
-
<span
|
|
1021
|
-
style={{
|
|
1022
|
-
position: 'absolute',
|
|
1023
|
-
top: '-4px',
|
|
1024
|
-
right: '-4px',
|
|
1025
|
-
width: '14px',
|
|
1026
|
-
height: '14px',
|
|
1027
|
-
borderRadius: '50%',
|
|
1028
|
-
backgroundColor: '#FF3B30',
|
|
1029
|
-
color: 'white',
|
|
1030
|
-
fontSize: '10px',
|
|
1031
|
-
display: 'flex',
|
|
1032
|
-
alignItems: 'center',
|
|
1033
|
-
justifyContent: 'center',
|
|
1034
|
-
border: '1px solid rgba(255,255,255,0.8)',
|
|
1035
|
-
}}
|
|
1036
|
-
>
|
|
1037
|
-
{notificationCount}
|
|
1038
|
-
</span>
|
|
1039
|
-
)}
|
|
1040
|
-
</div>
|
|
1041
|
-
</div>
|
|
1042
|
-
</div>
|
|
1043
|
-
</AtomixGlass>
|
|
1044
|
-
{/* Center widget - iOS style with improved design */}
|
|
1045
|
-
<AtomixGlass
|
|
1046
|
-
displacementScale={15}
|
|
1047
|
-
blurAmount={2}
|
|
1048
|
-
saturation={150}
|
|
1049
|
-
aberrationIntensity={0.1}
|
|
1050
|
-
cornerRadius={24}
|
|
1051
|
-
mode="shader"
|
|
1052
|
-
>
|
|
1053
|
-
<div style={{ padding: '30px' }}>
|
|
1054
|
-
<h2
|
|
1055
|
-
style={{
|
|
1056
|
-
marginTop: 0,
|
|
1057
|
-
fontSize: '26px',
|
|
1058
|
-
fontWeight: 600,
|
|
1059
|
-
marginBottom: '24px',
|
|
1060
|
-
textAlign: 'center',
|
|
1061
|
-
background: 'linear-gradient(135deg, #007AFF, #5AC8FA)',
|
|
1062
|
-
WebkitBackgroundClip: 'text',
|
|
1063
|
-
WebkitTextFillColor: 'transparent',
|
|
1064
|
-
}}
|
|
1065
|
-
>
|
|
1066
|
-
Welcome to Atomix OS
|
|
1067
|
-
</h2>
|
|
1068
|
-
|
|
1069
|
-
{/* App grid with improved styling */}
|
|
1070
|
-
<div
|
|
1071
|
-
style={{
|
|
1072
|
-
display: 'grid',
|
|
1073
|
-
gridTemplateColumns: 'repeat(3, 1fr)',
|
|
1074
|
-
gap: '20px',
|
|
1075
|
-
marginBottom: '28px',
|
|
1076
|
-
}}
|
|
1077
|
-
>
|
|
1078
|
-
{appIcons.map(app => (
|
|
1079
|
-
<div
|
|
1080
|
-
key={app.name}
|
|
1081
|
-
style={{
|
|
1082
|
-
display: 'flex',
|
|
1083
|
-
flexDirection: 'column',
|
|
1084
|
-
alignItems: 'center',
|
|
1085
|
-
gap: '8px',
|
|
1086
|
-
}}
|
|
1087
|
-
>
|
|
1088
|
-
<div
|
|
1089
|
-
style={{
|
|
1090
|
-
width: '56px',
|
|
1091
|
-
height: '56px',
|
|
1092
|
-
borderRadius: '14px',
|
|
1093
|
-
background: app.color,
|
|
1094
|
-
display: 'flex',
|
|
1095
|
-
alignItems: 'center',
|
|
1096
|
-
justifyContent: 'center',
|
|
1097
|
-
fontSize: '24px',
|
|
1098
|
-
boxShadow: '0 4px 10px rgba(0,0,0,0.15)',
|
|
1099
|
-
transition: 'transform 0.2s ease, box-shadow 0.2s ease',
|
|
1100
|
-
cursor: 'pointer',
|
|
1101
|
-
transform: 'translateY(0)',
|
|
1102
|
-
// Note: React inline styles don't support pseudo-classes like :hover
|
|
1103
|
-
// For hover effects, use CSS classes or onMouseEnter/onMouseLeave handlers
|
|
1104
|
-
}}
|
|
1105
|
-
>
|
|
1106
|
-
{app.symbol}
|
|
1107
|
-
</div>
|
|
1108
|
-
<span
|
|
1109
|
-
style={{
|
|
1110
|
-
fontSize: '13px',
|
|
1111
|
-
fontWeight: 500,
|
|
1112
|
-
opacity: 0.9,
|
|
1113
|
-
}}
|
|
1114
|
-
>
|
|
1115
|
-
{app.name}
|
|
1116
|
-
</span>
|
|
1117
|
-
</div>
|
|
1118
|
-
))}
|
|
1119
|
-
</div>
|
|
1120
|
-
|
|
1121
|
-
{/* Notification card with improved design */}
|
|
1122
|
-
<AtomixGlass
|
|
1123
|
-
displacementScale={12}
|
|
1124
|
-
blurAmount={5}
|
|
1125
|
-
saturation={130}
|
|
1126
|
-
aberrationIntensity={1}
|
|
1127
|
-
cornerRadius={16}
|
|
1128
|
-
elasticity={0}
|
|
1129
|
-
mode="shader"
|
|
1130
|
-
>
|
|
1131
|
-
<div style={{ padding: '18px', fontSize: '14px' }}>
|
|
1132
|
-
<div
|
|
1133
|
-
style={{
|
|
1134
|
-
display: 'flex',
|
|
1135
|
-
alignItems: 'center',
|
|
1136
|
-
justifyContent: 'space-between',
|
|
1137
|
-
marginBottom: '12px',
|
|
1138
|
-
}}
|
|
1139
|
-
>
|
|
1140
|
-
<div
|
|
1141
|
-
style={{
|
|
1142
|
-
display: 'flex',
|
|
1143
|
-
alignItems: 'center',
|
|
1144
|
-
gap: '8px',
|
|
1145
|
-
fontWeight: 600,
|
|
1146
|
-
}}
|
|
1147
|
-
>
|
|
1148
|
-
<span style={{ fontSize: '16px' }}>📣</span>
|
|
1149
|
-
<span>Notifications</span>
|
|
1150
|
-
</div>
|
|
1151
|
-
<span
|
|
1152
|
-
style={{
|
|
1153
|
-
fontSize: '12px',
|
|
1154
|
-
padding: '2px 8px',
|
|
1155
|
-
borderRadius: '10px',
|
|
1156
|
-
background: 'rgba(255,45,85,0.2)',
|
|
1157
|
-
color: '#FF2D55',
|
|
1158
|
-
fontWeight: 600,
|
|
1159
|
-
}}
|
|
1160
|
-
>
|
|
1161
|
-
{notificationCount} New
|
|
1162
|
-
</span>
|
|
1163
|
-
</div>
|
|
1164
|
-
|
|
1165
|
-
<div
|
|
1166
|
-
style={{
|
|
1167
|
-
padding: '10px 0',
|
|
1168
|
-
borderTop: '1px solid rgba(255,255,255,0.1)',
|
|
1169
|
-
display: 'flex',
|
|
1170
|
-
alignItems: 'center',
|
|
1171
|
-
justifyContent: 'space-between',
|
|
1172
|
-
}}
|
|
1173
|
-
>
|
|
1174
|
-
<div>
|
|
1175
|
-
<div style={{ fontWeight: 500, marginBottom: '4px' }}>
|
|
1176
|
-
New Atomix Glass Component
|
|
1177
|
-
</div>
|
|
1178
|
-
<div style={{ fontSize: '12px', opacity: 0.8 }}>
|
|
1179
|
-
Experience the next generation of UI effects
|
|
1180
|
-
</div>
|
|
1181
|
-
</div>
|
|
1182
|
-
<div
|
|
1183
|
-
style={{
|
|
1184
|
-
width: '36px',
|
|
1185
|
-
height: '36px',
|
|
1186
|
-
borderRadius: '8px',
|
|
1187
|
-
background: 'linear-gradient(135deg, #007AFF, #5AC8FA)',
|
|
1188
|
-
display: 'flex',
|
|
1189
|
-
alignItems: 'center',
|
|
1190
|
-
justifyContent: 'center',
|
|
1191
|
-
fontSize: '18px',
|
|
1192
|
-
}}
|
|
1193
|
-
>
|
|
1194
|
-
✨
|
|
1195
|
-
</div>
|
|
1196
|
-
</div>
|
|
1197
|
-
</div>
|
|
1198
|
-
</AtomixGlass>
|
|
1199
|
-
</div>
|
|
1200
|
-
</AtomixGlass>
|
|
1201
|
-
|
|
1202
|
-
{/* Bottom dock - macOS style with improved design and hover effects */}
|
|
1203
|
-
<AtomixGlass
|
|
1204
|
-
displacementScale={15}
|
|
1205
|
-
blurAmount={2}
|
|
1206
|
-
saturation={140}
|
|
1207
|
-
aberrationIntensity={1.2}
|
|
1208
|
-
cornerRadius={24}
|
|
1209
|
-
mode="polar"
|
|
1210
|
-
style={{
|
|
1211
|
-
maxWidth: '600px',
|
|
1212
|
-
}}
|
|
1213
|
-
>
|
|
1214
|
-
<div
|
|
1215
|
-
style={{
|
|
1216
|
-
display: 'flex',
|
|
1217
|
-
justifyContent: 'center',
|
|
1218
|
-
alignItems: 'center',
|
|
1219
|
-
gap: '16px',
|
|
1220
|
-
padding: '6px',
|
|
1221
|
-
}}
|
|
1222
|
-
>
|
|
1223
|
-
{dockApps.map((app, index) => (
|
|
1224
|
-
<div
|
|
1225
|
-
key={index}
|
|
1226
|
-
style={{
|
|
1227
|
-
width: '48px',
|
|
1228
|
-
height: '48px',
|
|
1229
|
-
borderRadius: '12px',
|
|
1230
|
-
background: app.color,
|
|
1231
|
-
display: 'flex',
|
|
1232
|
-
alignItems: 'center',
|
|
1233
|
-
justifyContent: 'center',
|
|
1234
|
-
fontSize: '20px',
|
|
1235
|
-
cursor: 'pointer',
|
|
1236
|
-
transition: 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
1237
|
-
transform:
|
|
1238
|
-
hoverDockItem === index
|
|
1239
|
-
? 'translateY(-10px) scale(1.1)'
|
|
1240
|
-
: 'translateY(0) scale(1)',
|
|
1241
|
-
boxShadow:
|
|
1242
|
-
hoverDockItem === index
|
|
1243
|
-
? '0 10px 20px rgba(0,0,0,0.2)'
|
|
1244
|
-
: '0 4px 10px rgba(0,0,0,0.1)',
|
|
1245
|
-
position: 'relative',
|
|
1246
|
-
}}
|
|
1247
|
-
onMouseEnter={() => setHoverDockItem(index)}
|
|
1248
|
-
onMouseLeave={() => setHoverDockItem(null)}
|
|
1249
|
-
>
|
|
1250
|
-
{app.symbol}
|
|
1251
|
-
{/* App name tooltip on hover */}
|
|
1252
|
-
{hoverDockItem === index && (
|
|
1253
|
-
<div
|
|
1254
|
-
style={{
|
|
1255
|
-
position: 'absolute',
|
|
1256
|
-
top: '-30px',
|
|
1257
|
-
left: '50%',
|
|
1258
|
-
transform: 'translateX(-50%)',
|
|
1259
|
-
background: 'rgba(0,0,0,0.7)',
|
|
1260
|
-
color: 'white',
|
|
1261
|
-
padding: '4px 10px',
|
|
1262
|
-
borderRadius: '6px',
|
|
1263
|
-
fontSize: '12px',
|
|
1264
|
-
fontWeight: 500,
|
|
1265
|
-
whiteSpace: 'nowrap',
|
|
1266
|
-
}}
|
|
1267
|
-
>
|
|
1268
|
-
{app.name}
|
|
1269
|
-
</div>
|
|
1270
|
-
)}
|
|
1271
|
-
</div>
|
|
1272
|
-
))}
|
|
1273
|
-
|
|
1274
|
-
{/* Separator line */}
|
|
1275
|
-
<div
|
|
1276
|
-
style={{
|
|
1277
|
-
width: '1px',
|
|
1278
|
-
height: '30px',
|
|
1279
|
-
background: 'rgba(255,255,255,0.3)',
|
|
1280
|
-
margin: '0 4px',
|
|
1281
|
-
}}
|
|
1282
|
-
></div>
|
|
1283
|
-
|
|
1284
|
-
{/* Trash icon */}
|
|
1285
|
-
<div
|
|
1286
|
-
style={{
|
|
1287
|
-
width: '48px',
|
|
1288
|
-
height: '48px',
|
|
1289
|
-
borderRadius: '12px',
|
|
1290
|
-
background: 'rgba(255,255,255,0.2)',
|
|
1291
|
-
display: 'flex',
|
|
1292
|
-
alignItems: 'center',
|
|
1293
|
-
justifyContent: 'center',
|
|
1294
|
-
fontSize: '20px',
|
|
1295
|
-
cursor: 'pointer',
|
|
1296
|
-
transition: 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
1297
|
-
transform:
|
|
1298
|
-
hoverDockItem === 999
|
|
1299
|
-
? 'translateY(-10px) scale(1.1)'
|
|
1300
|
-
: 'translateY(0) scale(1)',
|
|
1301
|
-
boxShadow:
|
|
1302
|
-
hoverDockItem === 999
|
|
1303
|
-
? '0 10px 20px rgba(0,0,0,0.2)'
|
|
1304
|
-
: '0 4px 10px rgba(0,0,0,0.1)',
|
|
1305
|
-
}}
|
|
1306
|
-
onMouseEnter={() => setHoverDockItem(999)}
|
|
1307
|
-
onMouseLeave={() => setHoverDockItem(null)}
|
|
1308
|
-
>
|
|
1309
|
-
🗑️
|
|
1310
|
-
</div>
|
|
1311
|
-
</div>
|
|
1312
|
-
</AtomixGlass>
|
|
1313
|
-
</div>
|
|
1314
|
-
</BackgroundWrapper>
|
|
1315
|
-
);
|
|
1316
|
-
},
|
|
1317
|
-
parameters: {
|
|
1318
|
-
docs: {
|
|
1319
|
-
description: {
|
|
1320
|
-
story:
|
|
1321
|
-
'An enhanced Apple-inspired UI example showcasing how to create macOS and iOS-like interfaces using the AtomixGlass component. This example includes a realistic menu bar with status icons, app grid with gradient icons, notification center, and an interactive dock with hover effects - all with the signature Apple frosted glass aesthetic.',
|
|
1322
|
-
},
|
|
1323
|
-
},
|
|
1324
|
-
},
|
|
1325
|
-
};
|
|
1326
|
-
|
|
1327
|
-
// Hero section example
|
|
1328
|
-
export const HeroExample: Story = {
|
|
1329
|
-
render: () => (
|
|
1330
|
-
<BackgroundWrapper backgroundImage={backgroundImages[0]} height="90vh">
|
|
1331
|
-
<div>
|
|
1332
|
-
<div
|
|
1333
|
-
style={{
|
|
1334
|
-
display: 'flex',
|
|
1335
|
-
flexDirection: 'column',
|
|
1336
|
-
alignItems: 'center',
|
|
1337
|
-
textAlign: 'center',
|
|
1338
|
-
}}
|
|
1339
|
-
>
|
|
1340
|
-
<AtomixGlass
|
|
1341
|
-
displacementScale={45}
|
|
1342
|
-
blurAmount={0.08}
|
|
1343
|
-
saturation={170}
|
|
1344
|
-
aberrationIntensity={2.5}
|
|
1345
|
-
elasticity={0.18}
|
|
1346
|
-
cornerRadius={30}
|
|
1347
|
-
mode="standard"
|
|
1348
|
-
style={{ maxWidth: '800px' }}
|
|
1349
|
-
>
|
|
1350
|
-
<div style={{ padding: '40px 60px' }}>
|
|
1351
|
-
<h1 style={{ marginTop: 0, fontSize: '2.5rem' }}>Modern Glass UI</h1>
|
|
1352
|
-
<p style={{ fontSize: '1.2rem', marginBottom: '30px' }}>
|
|
1353
|
-
Create stunning interfaces with the AtomixGlass component. Perfect for modern, sleek
|
|
1354
|
-
designs that stand out.
|
|
1355
|
-
</p>
|
|
1356
|
-
<div
|
|
1357
|
-
style={{ display: 'flex', gap: '15px', justifyContent: 'center', flexWrap: 'wrap' }}
|
|
1358
|
-
>
|
|
1359
|
-
<button className="c-btn c-btn--primary">Get Started</button>
|
|
1360
|
-
<button className="c-btn c-btn--outline-light">Learn More</button>
|
|
1361
|
-
</div>
|
|
1362
|
-
</div>
|
|
1363
|
-
</AtomixGlass>
|
|
1364
|
-
</div>
|
|
1365
|
-
</div>
|
|
1366
|
-
</BackgroundWrapper>
|
|
1367
|
-
),
|
|
1368
|
-
};
|
|
1369
|
-
|
|
1370
|
-
export const PerformanceOptimization: Story = {
|
|
1371
|
-
parameters: {
|
|
1372
|
-
docs: {
|
|
1373
|
-
description: {
|
|
1374
|
-
story:
|
|
1375
|
-
'This example demonstrates performance optimization techniques for the AtomixGlass component. It shows how different settings affect performance and provides best practices for optimal usage.',
|
|
1376
|
-
},
|
|
1377
|
-
},
|
|
1378
|
-
},
|
|
1379
|
-
render: () => (
|
|
1380
|
-
<BackgroundWrapper backgroundIndex={3} overlay={true}>
|
|
1381
|
-
<div style={{ maxWidth: '1200px', margin: '0 auto', padding: '40px 20px' }}>
|
|
1382
|
-
<h2 style={{ color: '#fff', marginBottom: '30px', textAlign: 'center' }}>
|
|
1383
|
-
Performance Optimization Guide
|
|
1384
|
-
</h2>
|
|
1385
|
-
|
|
1386
|
-
<div
|
|
1387
|
-
style={{
|
|
1388
|
-
marginBottom: '40px',
|
|
1389
|
-
backgroundColor: 'rgba(0,0,0,0.7)',
|
|
1390
|
-
padding: '20px',
|
|
1391
|
-
borderRadius: '10px',
|
|
1392
|
-
}}
|
|
1393
|
-
>
|
|
1394
|
-
<h3 style={{ color: '#fff', marginBottom: '15px' }}>Best Practices</h3>
|
|
1395
|
-
<ul style={{ color: '#fff', lineHeight: '1.6' }}>
|
|
1396
|
-
<li>
|
|
1397
|
-
<strong>Limit the number of instances</strong> - Use AtomixGlass components sparingly
|
|
1398
|
-
on a single page
|
|
1399
|
-
</li>
|
|
1400
|
-
<li>
|
|
1401
|
-
<strong>Optimize size</strong> - Smaller glass components perform better than
|
|
1402
|
-
full-screen ones
|
|
1403
|
-
</li>
|
|
1404
|
-
<li>
|
|
1405
|
-
<strong>Reduce complexity for mobile</strong> - Use simpler settings on mobile devices
|
|
1406
|
-
</li>
|
|
1407
|
-
<li>
|
|
1408
|
-
<strong>Disable effects when not needed</strong> - Turn off hover effects for
|
|
1409
|
-
non-interactive elements
|
|
1410
|
-
</li>
|
|
1411
|
-
<li>
|
|
1412
|
-
<strong>Use appropriate mode</strong> - Choose the right mode based on performance
|
|
1413
|
-
requirements
|
|
1414
|
-
</li>
|
|
1415
|
-
</ul>
|
|
1416
|
-
</div>
|
|
1417
|
-
|
|
1418
|
-
<div className="o-grid">
|
|
1419
|
-
<div className="o-grid__row">
|
|
1420
|
-
<div className="o-grid__col o-grid__col--12 o-grid__col--6@md">
|
|
1421
|
-
<h3 style={{ color: '#fff', marginBottom: '15px' }}>
|
|
1422
|
-
High Performance Configuration
|
|
1423
|
-
</h3>
|
|
1424
|
-
<AtomixGlass
|
|
1425
|
-
displacementScale={25}
|
|
1426
|
-
blurAmount={0.02}
|
|
1427
|
-
saturation={120}
|
|
1428
|
-
aberrationIntensity={0.8}
|
|
1429
|
-
elasticity={0.1}
|
|
1430
|
-
cornerRadius={10}
|
|
1431
|
-
mode="standard"
|
|
1432
|
-
reducedMotion={false}
|
|
1433
|
-
disableEffects={false}
|
|
1434
|
-
style={{ height: '100%', minHeight: '200px' }}
|
|
1435
|
-
>
|
|
1436
|
-
<div style={{ padding: '20px' }}>
|
|
1437
|
-
<h4 style={{ marginTop: 0 }}>Optimized for Performance</h4>
|
|
1438
|
-
<p>This configuration prioritizes performance over visual effects:</p>
|
|
1439
|
-
<ul>
|
|
1440
|
-
<li>Low displacement scale (25)</li>
|
|
1441
|
-
<li>Minimal blur amount (0.02)</li>
|
|
1442
|
-
<li>Reduced saturation (120%)</li>
|
|
1443
|
-
<li>Simple mode with no hover effects</li>
|
|
1444
|
-
<li>No border effects</li>
|
|
1445
|
-
</ul>
|
|
1446
|
-
<p>
|
|
1447
|
-
<strong>Best for:</strong> Mobile devices, pages with multiple instances, or
|
|
1448
|
-
low-end hardware
|
|
1449
|
-
</p>
|
|
1450
|
-
</div>
|
|
1451
|
-
</AtomixGlass>
|
|
1452
|
-
</div>
|
|
1453
|
-
|
|
1454
|
-
<div className="o-grid__col o-grid__col--12 o-grid__col--6@md">
|
|
1455
|
-
<h3 style={{ color: '#fff', marginBottom: '15px' }}>Balanced Configuration</h3>
|
|
1456
|
-
<AtomixGlass
|
|
1457
|
-
displacementScale={55}
|
|
1458
|
-
blurAmount={0.04}
|
|
1459
|
-
saturation={150}
|
|
1460
|
-
aberrationIntensity={1.8}
|
|
1461
|
-
elasticity={0.15}
|
|
1462
|
-
cornerRadius={15}
|
|
1463
|
-
mode="standard"
|
|
1464
|
-
enablePerformanceMonitoring={true}
|
|
1465
|
-
style={{ height: '100%', minHeight: '200px' }}
|
|
1466
|
-
>
|
|
1467
|
-
<div style={{ padding: '20px' }}>
|
|
1468
|
-
<h4 style={{ marginTop: 0 }}>Balanced Approach</h4>
|
|
1469
|
-
<p>This configuration balances performance and visual appeal:</p>
|
|
1470
|
-
<ul>
|
|
1471
|
-
<li>Moderate displacement scale (55)</li>
|
|
1472
|
-
<li>Medium blur amount (0.04)</li>
|
|
1473
|
-
<li>Balanced saturation (150%)</li>
|
|
1474
|
-
<li>Normal mode with subtle hover effects</li>
|
|
1475
|
-
<li>Minimal border effects</li>
|
|
1476
|
-
</ul>
|
|
1477
|
-
<p>
|
|
1478
|
-
<strong>Best for:</strong> Most desktop applications and modern devices
|
|
1479
|
-
</p>
|
|
1480
|
-
</div>
|
|
1481
|
-
</AtomixGlass>
|
|
1482
|
-
</div>
|
|
1483
|
-
</div>
|
|
1484
|
-
|
|
1485
|
-
<div className="o-grid__row" style={{ marginTop: '30px' }}>
|
|
1486
|
-
<div className="o-grid__col o-grid__col--12">
|
|
1487
|
-
<div
|
|
1488
|
-
style={{
|
|
1489
|
-
backgroundColor: 'rgba(0,0,0,0.7)',
|
|
1490
|
-
padding: '20px',
|
|
1491
|
-
borderRadius: '10px',
|
|
1492
|
-
}}
|
|
1493
|
-
>
|
|
1494
|
-
<h3 style={{ color: '#fff', marginBottom: '15px' }}>Performance Monitoring Tips</h3>
|
|
1495
|
-
<ol style={{ color: '#fff', lineHeight: '1.6' }}>
|
|
1496
|
-
<li>Use browser developer tools to monitor performance</li>
|
|
1497
|
-
<li>Check for dropped frames in the Performance panel</li>
|
|
1498
|
-
<li>Monitor GPU usage when using advanced effects</li>
|
|
1499
|
-
<li>Test on various devices to ensure consistent performance</li>
|
|
1500
|
-
<li>
|
|
1501
|
-
Consider using the <code>React.memo</code> HOC to prevent unnecessary re-renders
|
|
1502
|
-
</li>
|
|
1503
|
-
</ol>
|
|
1504
|
-
|
|
1505
|
-
<div
|
|
1506
|
-
style={{
|
|
1507
|
-
marginTop: '20px',
|
|
1508
|
-
padding: '15px',
|
|
1509
|
-
backgroundColor: 'rgba(255,255,255,0.1)',
|
|
1510
|
-
borderRadius: '5px',
|
|
1511
|
-
}}
|
|
1512
|
-
>
|
|
1513
|
-
<h4 style={{ color: '#fff', marginBottom: '10px' }}>
|
|
1514
|
-
Code Example: Optimized Usage
|
|
1515
|
-
</h4>
|
|
1516
|
-
<pre
|
|
1517
|
-
style={{
|
|
1518
|
-
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
1519
|
-
padding: '15px',
|
|
1520
|
-
borderRadius: '5px',
|
|
1521
|
-
overflow: 'auto',
|
|
1522
|
-
}}
|
|
1523
|
-
>
|
|
1524
|
-
<code style={{ color: '#e6e6e6', display: 'block', fontFamily: 'monospace' }}>
|
|
1525
|
-
{`import React, { memo } from 'react';
|
|
1526
|
-
import AtomixGlass from './AtomixGlass';
|
|
1527
|
-
|
|
1528
|
-
// Use memo to prevent unnecessary re-renders
|
|
1529
|
-
const OptimizedGlassCard = memo(({ title, content }) => {
|
|
1530
|
-
// Adjust settings based on device capability
|
|
1531
|
-
const isMobile = window.innerWidth < 768;
|
|
1532
|
-
|
|
1533
|
-
return (
|
|
1534
|
-
<AtomixGlass
|
|
1535
|
-
displacementScale={isMobile ? 10 : 20}
|
|
1536
|
-
blurAmount={isMobile ? 5 : 10}
|
|
1537
|
-
saturation={isMobile ? 120 : 150}
|
|
1538
|
-
aberrationIntensity={isMobile ? 0.5 : 1.5}
|
|
1539
|
-
mode={isMobile ? "simple" : "normal"}
|
|
1540
|
-
showHoverEffects={!isMobile}
|
|
1541
|
-
>
|
|
1542
|
-
<div style={{ padding: '20px' }}>
|
|
1543
|
-
<h3>{title}</h3>
|
|
1544
|
-
<p>{content}</p>
|
|
1545
|
-
</div>
|
|
1546
|
-
</AtomixGlass>
|
|
1547
|
-
);
|
|
1548
|
-
});
|
|
1549
|
-
|
|
1550
|
-
export default OptimizedGlassCard;`}
|
|
1551
|
-
</code>
|
|
1552
|
-
</pre>
|
|
1553
|
-
</div>
|
|
1554
|
-
</div>
|
|
1555
|
-
</div>
|
|
1556
|
-
</div>
|
|
1557
|
-
</div>
|
|
1558
|
-
</div>
|
|
1559
|
-
</BackgroundWrapper>
|
|
1560
|
-
),
|
|
1561
|
-
};
|
|
1562
|
-
|
|
1563
|
-
/**
|
|
1564
|
-
* Interactive Playground story with dynamic controls for all component props
|
|
1565
|
-
*
|
|
1566
|
-
* This story provides a comprehensive playground for experimenting with all
|
|
1567
|
-
* AtomixGlass component properties in real-time.
|
|
1568
|
-
*/
|
|
1569
|
-
export const InteractivePlayground: Story = {
|
|
1570
|
-
render: () => {
|
|
1571
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
1572
|
-
const [settings, setSettings] = useState({
|
|
1573
|
-
displacementScale: 70,
|
|
1574
|
-
blurAmount: 1,
|
|
1575
|
-
saturation: 140,
|
|
1576
|
-
aberrationIntensity: 2,
|
|
1577
|
-
cornerRadius: 20,
|
|
1578
|
-
mode: 'standard' as const,
|
|
1579
|
-
showBorderEffects: true,
|
|
1580
|
-
showHoverEffects: true,
|
|
1581
|
-
overLight: false,
|
|
1582
|
-
background: backgrounds.blueGradient,
|
|
1583
|
-
useVideoBackground: false,
|
|
1584
|
-
elasticity: 0.15,
|
|
1585
|
-
});
|
|
1586
|
-
|
|
1587
|
-
const handleChange = (property: string, value: any) => {
|
|
1588
|
-
setSettings(prev => ({
|
|
1589
|
-
...prev,
|
|
1590
|
-
[property]: value,
|
|
1591
|
-
}));
|
|
1592
|
-
};
|
|
1593
|
-
|
|
1594
|
-
const modes = ['standard', 'polar', 'prominent', 'shader'] as const;
|
|
1595
|
-
const backgroundOptions = Object.entries(backgrounds).map(([key, value]) => ({
|
|
1596
|
-
label: key,
|
|
1597
|
-
value,
|
|
1598
|
-
}));
|
|
1599
|
-
|
|
1600
|
-
// Control panel styles
|
|
1601
|
-
const controlPanelStyle = {
|
|
1602
|
-
width: '400px',
|
|
1603
|
-
padding: '20px',
|
|
1604
|
-
borderRadius: '12px',
|
|
1605
|
-
background: 'rgba(0,0,0,0.7)',
|
|
1606
|
-
boxShadow: '0 4px 20px rgba(0,0,0,0.3)',
|
|
1607
|
-
color: 'white',
|
|
1608
|
-
fontSize: '14px',
|
|
1609
|
-
};
|
|
1610
|
-
|
|
1611
|
-
const sliderContainerStyle = {
|
|
1612
|
-
marginBottom: '16px',
|
|
1613
|
-
};
|
|
1614
|
-
|
|
1615
|
-
const sliderLabelStyle = {
|
|
1616
|
-
display: 'flex',
|
|
1617
|
-
justifyContent: 'space-between',
|
|
1618
|
-
marginBottom: '6px',
|
|
1619
|
-
};
|
|
1620
|
-
|
|
1621
|
-
const sliderStyle = {
|
|
1622
|
-
width: '100%',
|
|
1623
|
-
accentColor: '#6366f1',
|
|
1624
|
-
};
|
|
1625
|
-
|
|
1626
|
-
const selectStyle = {
|
|
1627
|
-
width: '100%',
|
|
1628
|
-
padding: '8px',
|
|
1629
|
-
backgroundColor: 'rgba(255,255,255,0.1)',
|
|
1630
|
-
color: 'white',
|
|
1631
|
-
border: '1px solid rgba(255,255,255,0.2)',
|
|
1632
|
-
borderRadius: '4px',
|
|
1633
|
-
marginBottom: '16px',
|
|
1634
|
-
};
|
|
1635
|
-
|
|
1636
|
-
const checkboxContainerStyle = {
|
|
1637
|
-
display: 'flex',
|
|
1638
|
-
alignItems: 'center',
|
|
1639
|
-
marginBottom: '12px',
|
|
1640
|
-
gap: '8px',
|
|
1641
|
-
};
|
|
1642
|
-
|
|
1643
|
-
return (
|
|
1644
|
-
<BackgroundWrapper
|
|
1645
|
-
backgroundImage={settings.useVideoBackground ? 'transparent' : settings.background}
|
|
1646
|
-
height="80vh"
|
|
1647
|
-
style={{ maxWidth: '1400px', position: 'relative', overflow: 'hidden' }}
|
|
1648
|
-
>
|
|
1649
|
-
{/* Control Panel */}
|
|
1650
|
-
<div style={controlPanelStyle}>
|
|
1651
|
-
<h3 style={{ margin: '0 0 16px 0', fontSize: '18px', textAlign: 'center' }}>
|
|
1652
|
-
AtomixGlass Controls
|
|
1653
|
-
</h3>
|
|
1654
|
-
|
|
1655
|
-
{/* Displacement Scale */}
|
|
1656
|
-
<div style={sliderContainerStyle}>
|
|
1657
|
-
<div style={sliderLabelStyle}>
|
|
1658
|
-
<label htmlFor="displacementScale">Displacement Scale</label>
|
|
1659
|
-
<span>{settings.displacementScale}</span>
|
|
1660
|
-
</div>
|
|
1661
|
-
<input
|
|
1662
|
-
type="range"
|
|
1663
|
-
id="displacementScale"
|
|
1664
|
-
min="0"
|
|
1665
|
-
max="100"
|
|
1666
|
-
value={settings.displacementScale}
|
|
1667
|
-
onChange={e => handleChange('displacementScale', parseInt(e.target.value))}
|
|
1668
|
-
style={sliderStyle}
|
|
1669
|
-
/>
|
|
1670
|
-
</div>
|
|
1671
|
-
|
|
1672
|
-
{/* Blur Amount */}
|
|
1673
|
-
<div style={sliderContainerStyle}>
|
|
1674
|
-
<div style={sliderLabelStyle}>
|
|
1675
|
-
<label htmlFor="blurAmount">Blur Amount</label>
|
|
1676
|
-
<span>{settings.blurAmount}</span>
|
|
1677
|
-
</div>
|
|
1678
|
-
<input
|
|
1679
|
-
type="range"
|
|
1680
|
-
id="blurAmount"
|
|
1681
|
-
min="0"
|
|
1682
|
-
max="20"
|
|
1683
|
-
step="0.05"
|
|
1684
|
-
value={settings.blurAmount}
|
|
1685
|
-
onChange={e => handleChange('blurAmount', parseFloat(e.target.value))}
|
|
1686
|
-
style={sliderStyle}
|
|
1687
|
-
/>
|
|
1688
|
-
</div>
|
|
1689
|
-
|
|
1690
|
-
{/* Saturation */}
|
|
1691
|
-
<div style={sliderContainerStyle}>
|
|
1692
|
-
<div style={sliderLabelStyle}>
|
|
1693
|
-
<label htmlFor="saturation">Saturation</label>
|
|
1694
|
-
<span>{settings.saturation}%</span>
|
|
1695
|
-
</div>
|
|
1696
|
-
<input
|
|
1697
|
-
type="range"
|
|
1698
|
-
id="saturation"
|
|
1699
|
-
min="0"
|
|
1700
|
-
max="300"
|
|
1701
|
-
value={settings.saturation}
|
|
1702
|
-
onChange={e => handleChange('saturation', parseInt(e.target.value))}
|
|
1703
|
-
style={sliderStyle}
|
|
1704
|
-
/>
|
|
1705
|
-
</div>
|
|
1706
|
-
|
|
1707
|
-
{/* Aberration Intensity */}
|
|
1708
|
-
<div style={sliderContainerStyle}>
|
|
1709
|
-
<div style={sliderLabelStyle}>
|
|
1710
|
-
<label htmlFor="aberrationIntensity">Aberration Intensity</label>
|
|
1711
|
-
<span>{settings.aberrationIntensity}</span>
|
|
1712
|
-
</div>
|
|
1713
|
-
<input
|
|
1714
|
-
type="range"
|
|
1715
|
-
id="aberrationIntensity"
|
|
1716
|
-
min="0"
|
|
1717
|
-
max="10"
|
|
1718
|
-
step="0.1"
|
|
1719
|
-
value={settings.aberrationIntensity}
|
|
1720
|
-
onChange={e => handleChange('aberrationIntensity', parseFloat(e.target.value))}
|
|
1721
|
-
style={sliderStyle}
|
|
1722
|
-
/>
|
|
1723
|
-
</div>
|
|
1724
|
-
|
|
1725
|
-
{/* Corner Radius */}
|
|
1726
|
-
<div style={sliderContainerStyle}>
|
|
1727
|
-
<div style={sliderLabelStyle}>
|
|
1728
|
-
<label htmlFor="cornerRadius">Corner Radius</label>
|
|
1729
|
-
<span>{settings.cornerRadius}px</span>
|
|
1730
|
-
</div>
|
|
1731
|
-
<input
|
|
1732
|
-
type="range"
|
|
1733
|
-
id="cornerRadius"
|
|
1734
|
-
min="0"
|
|
1735
|
-
max="50"
|
|
1736
|
-
value={settings.cornerRadius}
|
|
1737
|
-
onChange={e => handleChange('cornerRadius', parseInt(e.target.value))}
|
|
1738
|
-
style={sliderStyle}
|
|
1739
|
-
/>
|
|
1740
|
-
</div>
|
|
1741
|
-
|
|
1742
|
-
{/* Elasticity */}
|
|
1743
|
-
<div style={sliderContainerStyle}>
|
|
1744
|
-
<div style={sliderLabelStyle}>
|
|
1745
|
-
<label htmlFor="elasticity">Elasticity</label>
|
|
1746
|
-
<span>{settings.elasticity}</span>
|
|
1747
|
-
</div>
|
|
1748
|
-
<input
|
|
1749
|
-
type="range"
|
|
1750
|
-
id="elasticity"
|
|
1751
|
-
min="0"
|
|
1752
|
-
max="1"
|
|
1753
|
-
step="0.01"
|
|
1754
|
-
value={settings.elasticity}
|
|
1755
|
-
onChange={e => handleChange('elasticity',e.target.value)}
|
|
1756
|
-
style={sliderStyle}
|
|
1757
|
-
/>
|
|
1758
|
-
</div>
|
|
1759
|
-
|
|
1760
|
-
{/* Mode Select */}
|
|
1761
|
-
<label htmlFor="mode" style={{ display: 'block', marginBottom: '6px' }}>
|
|
1762
|
-
Mode
|
|
1763
|
-
</label>
|
|
1764
|
-
<select
|
|
1765
|
-
id="mode"
|
|
1766
|
-
value={settings.mode}
|
|
1767
|
-
onChange={e => handleChange('mode', e.target.value)}
|
|
1768
|
-
style={selectStyle}
|
|
1769
|
-
>
|
|
1770
|
-
{modes.map(mode => (
|
|
1771
|
-
<option key={mode} value={mode}>
|
|
1772
|
-
{mode.charAt(0).toUpperCase() + mode.slice(1)}
|
|
1773
|
-
</option>
|
|
1774
|
-
))}
|
|
1775
|
-
</select>
|
|
1776
|
-
|
|
1777
|
-
{/* Background Select */}
|
|
1778
|
-
<label htmlFor="background" style={{ display: 'block', marginBottom: '6px' }}>
|
|
1779
|
-
Background
|
|
1780
|
-
</label>
|
|
1781
|
-
<select
|
|
1782
|
-
id="background"
|
|
1783
|
-
value={settings.background}
|
|
1784
|
-
onChange={e => handleChange('background', e.target.value)}
|
|
1785
|
-
style={selectStyle}
|
|
1786
|
-
>
|
|
1787
|
-
{backgroundOptions.map(option => (
|
|
1788
|
-
<option key={option.label} value={option.value}>
|
|
1789
|
-
{option.label}
|
|
1790
|
-
</option>
|
|
1791
|
-
))}
|
|
1792
|
-
</select>
|
|
1793
|
-
|
|
1794
|
-
{/* Checkboxes */}
|
|
1795
|
-
<div style={checkboxContainerStyle}>
|
|
1796
|
-
<input
|
|
1797
|
-
type="checkbox"
|
|
1798
|
-
id="showBorderEffects"
|
|
1799
|
-
checked={settings.showBorderEffects}
|
|
1800
|
-
onChange={e => handleChange('showBorderEffects', e.target.checked)}
|
|
1801
|
-
/>
|
|
1802
|
-
<label htmlFor="showBorderEffects">Show Border Effects</label>
|
|
1803
|
-
</div>
|
|
1804
|
-
|
|
1805
|
-
<div style={checkboxContainerStyle}>
|
|
1806
|
-
<input
|
|
1807
|
-
type="checkbox"
|
|
1808
|
-
id="showHoverEffects"
|
|
1809
|
-
checked={settings.showHoverEffects}
|
|
1810
|
-
onChange={e => handleChange('showHoverEffects', e.target.checked)}
|
|
1811
|
-
/>
|
|
1812
|
-
<label htmlFor="showHoverEffects">Show Hover Effects</label>
|
|
1813
|
-
</div>
|
|
1814
|
-
|
|
1815
|
-
<div style={checkboxContainerStyle}>
|
|
1816
|
-
<input
|
|
1817
|
-
type="checkbox"
|
|
1818
|
-
id="overLight"
|
|
1819
|
-
checked={settings.overLight}
|
|
1820
|
-
onChange={e => handleChange('overLight', e.target.checked)}
|
|
1821
|
-
/>
|
|
1822
|
-
<label htmlFor="overLight">Over Light</label>
|
|
1823
|
-
</div>
|
|
1824
|
-
|
|
1825
|
-
<div style={checkboxContainerStyle}>
|
|
1826
|
-
<input
|
|
1827
|
-
type="checkbox"
|
|
1828
|
-
id="useVideoBackground"
|
|
1829
|
-
checked={settings.useVideoBackground}
|
|
1830
|
-
onChange={e => handleChange('useVideoBackground', e.target.checked)}
|
|
1831
|
-
/>
|
|
1832
|
-
<label htmlFor="useVideoBackground">Use Video Background</label>
|
|
1833
|
-
</div>
|
|
1834
|
-
</div>
|
|
1835
|
-
|
|
1836
|
-
{/* Video Background */}
|
|
1837
|
-
{settings.useVideoBackground && (
|
|
1838
|
-
<video
|
|
1839
|
-
autoPlay
|
|
1840
|
-
loop
|
|
1841
|
-
muted
|
|
1842
|
-
playsInline
|
|
1843
|
-
style={{
|
|
1844
|
-
position: 'absolute',
|
|
1845
|
-
top: 0,
|
|
1846
|
-
left: 0,
|
|
1847
|
-
width: '100%',
|
|
1848
|
-
height: '100%',
|
|
1849
|
-
objectFit: 'cover',
|
|
1850
|
-
zIndex: -1,
|
|
1851
|
-
}}
|
|
1852
|
-
>
|
|
1853
|
-
<source src={backgrounds.videoBackground} type="video/mp4" />
|
|
1854
|
-
</video>
|
|
1855
|
-
)}
|
|
1856
|
-
|
|
1857
|
-
{/* Glass Component Preview */}
|
|
1858
|
-
<div
|
|
1859
|
-
style={{
|
|
1860
|
-
display: 'flex',
|
|
1861
|
-
justifyContent: 'center',
|
|
1862
|
-
alignItems: 'center',
|
|
1863
|
-
height: '100%',
|
|
1864
|
-
width: '100%',
|
|
1865
|
-
paddingLeft: '300px', // Make room for the control panel
|
|
1866
|
-
}}
|
|
1867
|
-
>
|
|
1868
|
-
<AtomixGlass
|
|
1869
|
-
displacementScale={settings.displacementScale}
|
|
1870
|
-
blurAmount={settings.blurAmount}
|
|
1871
|
-
saturation={settings.saturation}
|
|
1872
|
-
aberrationIntensity={settings.aberrationIntensity}
|
|
1873
|
-
cornerRadius={settings.cornerRadius}
|
|
1874
|
-
mode={settings.mode}
|
|
1875
|
-
overLight={settings.overLight}
|
|
1876
|
-
elasticity={settings.elasticity}
|
|
1877
|
-
style={{ width: '400px', maxWidth: '100%' }}
|
|
1878
|
-
>
|
|
1879
|
-
<div style={{ padding: '30px', textAlign: 'center' }}>
|
|
1880
|
-
<h2 style={{ marginTop: 0, fontSize: '24px', fontWeight: 500, marginBottom: '16px' }}>
|
|
1881
|
-
Interactive Preview
|
|
1882
|
-
</h2>
|
|
1883
|
-
<p style={{ fontSize: '16px', lineHeight: 1.6, marginBottom: '20px' }}>
|
|
1884
|
-
Adjust the controls on the left to see how different properties affect the glass
|
|
1885
|
-
effect in real-time.
|
|
1886
|
-
{settings.useVideoBackground &&
|
|
1887
|
-
' Try the video background for an enhanced experience!'}
|
|
1888
|
-
</p>
|
|
1889
|
-
<div
|
|
1890
|
-
style={{
|
|
1891
|
-
display: 'flex',
|
|
1892
|
-
justifyContent: 'center',
|
|
1893
|
-
gap: '12px',
|
|
1894
|
-
flexWrap: 'wrap',
|
|
1895
|
-
}}
|
|
1896
|
-
>
|
|
1897
|
-
<Button label="Primary" variant="primary" glass={{elasticity: 0}}/>
|
|
1898
|
-
<Button label="secondary" variant="secondary" glass={{elasticity: 0}}/>
|
|
1899
|
-
</div>
|
|
1900
|
-
</div>
|
|
1901
|
-
</AtomixGlass>
|
|
1902
|
-
</div>
|
|
1903
|
-
</BackgroundWrapper>
|
|
1904
|
-
);
|
|
1905
|
-
},
|
|
1906
|
-
parameters: {
|
|
1907
|
-
docs: {
|
|
1908
|
-
description: {
|
|
1909
|
-
story:
|
|
1910
|
-
'An interactive playground that allows you to experiment with all AtomixGlass component properties in real-time. Use the control panel to adjust settings and see how they affect the appearance and behavior of the glass effect. Toggle the video background option to see how the glass effect works with dynamic content.',
|
|
1911
|
-
},
|
|
1912
|
-
},
|
|
1913
|
-
},
|
|
1914
|
-
};
|
|
1915
|
-
|
|
1916
|
-
// Accessibility example
|
|
1917
|
-
/**
|
|
1918
|
-
* Accessible Example - Demonstrates accessibility best practices
|
|
1919
|
-
*
|
|
1920
|
-
* This story showcases how to implement accessibility features with AtomixGlass
|
|
1921
|
-
* components, ensuring they are usable by people with disabilities.
|
|
1922
|
-
*/
|
|
1923
|
-
export const AccessibleExample: Story = {
|
|
1924
|
-
render: () => (
|
|
1925
|
-
<BackgroundWrapper
|
|
1926
|
-
backgroundImage={backgrounds.abstract2}
|
|
1927
|
-
height="70vh"
|
|
1928
|
-
width="90vw"
|
|
1929
|
-
overlayOpacity={0.1}
|
|
1930
|
-
aria-hidden="false"
|
|
1931
|
-
>
|
|
1932
|
-
<AtomixGlass
|
|
1933
|
-
displacementScale={40}
|
|
1934
|
-
blurAmount={1}
|
|
1935
|
-
saturation={160}
|
|
1936
|
-
aberrationIntensity={1.5}
|
|
1937
|
-
elasticity={0}
|
|
1938
|
-
cornerRadius={15}
|
|
1939
|
-
aria-label="Contact form container"
|
|
1940
|
-
aria-describedby="form-description"
|
|
1941
|
-
role="region"
|
|
1942
|
-
tabIndex={-1}
|
|
1943
|
-
reducedMotion={false}
|
|
1944
|
-
highContrast={false}
|
|
1945
|
-
style={{
|
|
1946
|
-
width: '400px',
|
|
1947
|
-
cursor: 'default',
|
|
1948
|
-
}}
|
|
1949
|
-
>
|
|
1950
|
-
<div style={{ padding: '30px' }}>
|
|
1951
|
-
<h2
|
|
1952
|
-
id="form-title"
|
|
1953
|
-
style={{
|
|
1954
|
-
marginTop: 0,
|
|
1955
|
-
fontSize: '24px',
|
|
1956
|
-
marginBottom: '20px',
|
|
1957
|
-
color: '#ffffff',
|
|
1958
|
-
}}
|
|
1959
|
-
>
|
|
1960
|
-
Contact Us
|
|
1961
|
-
</h2>
|
|
1962
|
-
width: '80%',
|
|
1963
|
-
{/* Adding description for screen readers */}
|
|
1964
|
-
<p id="form-description" style={{ marginBottom: '20px', fontSize: '16px' }}>
|
|
1965
|
-
Please fill out the form below to get in touch with our team.
|
|
1966
|
-
</p>
|
|
1967
|
-
<form aria-describedby="form-description">
|
|
1968
|
-
<div style={{ marginBottom: '20px' }}>
|
|
1969
|
-
<label
|
|
1970
|
-
htmlFor="name"
|
|
1971
|
-
style={{
|
|
1972
|
-
display: 'block',
|
|
1973
|
-
marginBottom: '8px',
|
|
1974
|
-
fontWeight: 500,
|
|
1975
|
-
}}
|
|
1976
|
-
>
|
|
1977
|
-
Name{' '}
|
|
1978
|
-
<span aria-hidden="true" style={{ color: '#ff3b30' }}>
|
|
1979
|
-
*
|
|
1980
|
-
</span>
|
|
1981
|
-
</label>
|
|
1982
|
-
<input
|
|
1983
|
-
id="name"
|
|
1984
|
-
type="text"
|
|
1985
|
-
aria-required="true"
|
|
1986
|
-
aria-invalid="false"
|
|
1987
|
-
aria-describedby="name-error"
|
|
1988
|
-
style={{
|
|
1989
|
-
width: '100%',
|
|
1990
|
-
padding: '10px',
|
|
1991
|
-
borderRadius: '6px',
|
|
1992
|
-
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
1993
|
-
background: 'rgba(255, 255, 255, 0.1)',
|
|
1994
|
-
color: '#ffffff',
|
|
1995
|
-
fontSize: '16px',
|
|
1996
|
-
}}
|
|
1997
|
-
/>
|
|
1998
|
-
<div
|
|
1999
|
-
id="name-error"
|
|
2000
|
-
role="alert"
|
|
2001
|
-
style={{
|
|
2002
|
-
height: '20px',
|
|
2003
|
-
fontSize: '14px',
|
|
2004
|
-
color: '#ff3b30',
|
|
2005
|
-
marginTop: '4px',
|
|
2006
|
-
}}
|
|
2007
|
-
></div>
|
|
2008
|
-
</div>
|
|
2009
|
-
|
|
2010
|
-
<div style={{ marginBottom: '20px' }}>
|
|
2011
|
-
<label
|
|
2012
|
-
htmlFor="email"
|
|
2013
|
-
style={{
|
|
2014
|
-
display: 'block',
|
|
2015
|
-
marginBottom: '8px',
|
|
2016
|
-
fontWeight: 500,
|
|
2017
|
-
}}
|
|
2018
|
-
>
|
|
2019
|
-
Email{' '}
|
|
2020
|
-
<span aria-hidden="true" style={{ color: '#ff3b30' }}>
|
|
2021
|
-
*
|
|
2022
|
-
</span>
|
|
2023
|
-
</label>
|
|
2024
|
-
<input
|
|
2025
|
-
id="email"
|
|
2026
|
-
type="email"
|
|
2027
|
-
aria-required="true"
|
|
2028
|
-
aria-invalid="false"
|
|
2029
|
-
aria-describedby="email-error"
|
|
2030
|
-
style={{
|
|
2031
|
-
width: '100%',
|
|
2032
|
-
padding: '10px',
|
|
2033
|
-
borderRadius: '6px',
|
|
2034
|
-
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
2035
|
-
background: 'rgba(255, 255, 255, 0.1)',
|
|
2036
|
-
color: '#ffffff',
|
|
2037
|
-
fontSize: '16px',
|
|
2038
|
-
}}
|
|
2039
|
-
/>
|
|
2040
|
-
<div
|
|
2041
|
-
id="email-error"
|
|
2042
|
-
role="alert"
|
|
2043
|
-
style={{
|
|
2044
|
-
height: '20px',
|
|
2045
|
-
fontSize: '14px',
|
|
2046
|
-
color: '#ff3b30',
|
|
2047
|
-
marginTop: '4px',
|
|
2048
|
-
}}
|
|
2049
|
-
></div>
|
|
2050
|
-
</div>
|
|
2051
|
-
|
|
2052
|
-
<div style={{ marginBottom: '20px' }}>
|
|
2053
|
-
<label
|
|
2054
|
-
htmlFor="message"
|
|
2055
|
-
style={{
|
|
2056
|
-
display: 'block',
|
|
2057
|
-
marginBottom: '8px',
|
|
2058
|
-
fontWeight: 500,
|
|
2059
|
-
}}
|
|
2060
|
-
>
|
|
2061
|
-
Message{' '}
|
|
2062
|
-
<span aria-hidden="true" style={{ color: '#ff3b30' }}>
|
|
2063
|
-
*
|
|
2064
|
-
</span>
|
|
2065
|
-
</label>
|
|
2066
|
-
<textarea
|
|
2067
|
-
id="message"
|
|
2068
|
-
rows={4}
|
|
2069
|
-
aria-required="true"
|
|
2070
|
-
aria-invalid="false"
|
|
2071
|
-
aria-describedby="message-error"
|
|
2072
|
-
style={{
|
|
2073
|
-
width: '100%',
|
|
2074
|
-
padding: '10px',
|
|
2075
|
-
borderRadius: '6px',
|
|
2076
|
-
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
2077
|
-
background: 'rgba(255, 255, 255, 0.1)',
|
|
2078
|
-
color: '#ffffff',
|
|
2079
|
-
fontSize: '16px',
|
|
2080
|
-
resize: 'vertical',
|
|
2081
|
-
}}
|
|
2082
|
-
/>
|
|
2083
|
-
<div
|
|
2084
|
-
id="message-error"
|
|
2085
|
-
role="alert"
|
|
2086
|
-
style={{
|
|
2087
|
-
height: '20px',
|
|
2088
|
-
fontSize: '14px',
|
|
2089
|
-
color: '#ff3b30',
|
|
2090
|
-
marginTop: '4px',
|
|
2091
|
-
}}
|
|
2092
|
-
></div>
|
|
2093
|
-
</div>
|
|
2094
|
-
|
|
2095
|
-
<div style={{ marginBottom: '20px' }}>
|
|
2096
|
-
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
2097
|
-
<input
|
|
2098
|
-
id="privacy-policy"
|
|
2099
|
-
type="checkbox"
|
|
2100
|
-
aria-required="true"
|
|
2101
|
-
style={{
|
|
2102
|
-
marginRight: '10px',
|
|
2103
|
-
width: '18px',
|
|
2104
|
-
height: '18px',
|
|
2105
|
-
}}
|
|
2106
|
-
/>
|
|
2107
|
-
<label htmlFor="privacy-policy">
|
|
2108
|
-
I agree to the{' '}
|
|
2109
|
-
<a href="#" style={{ color: '#ffffff', textDecoration: 'underline' }}>
|
|
2110
|
-
Privacy Policy
|
|
2111
|
-
</a>
|
|
2112
|
-
</label>
|
|
2113
|
-
</div>
|
|
2114
|
-
</div>
|
|
2115
|
-
|
|
2116
|
-
<button type="submit" className="c-btn c-btn--primary" aria-label="Submit contact form">
|
|
2117
|
-
Send Message
|
|
2118
|
-
</button>
|
|
2119
|
-
</form>
|
|
2120
|
-
</div>
|
|
2121
|
-
</AtomixGlass>
|
|
2122
|
-
</BackgroundWrapper>
|
|
2123
|
-
),
|
|
2124
|
-
parameters: {
|
|
2125
|
-
docs: {
|
|
2126
|
-
description: {
|
|
2127
|
-
story:
|
|
2128
|
-
'An example showcasing accessibility features with the AtomixGlass component. This form includes proper ARIA attributes, semantic HTML, and keyboard navigation support.',
|
|
2129
|
-
},
|
|
2130
|
-
},
|
|
2131
|
-
},
|
|
2132
|
-
};
|
|
2133
|
-
|
|
2134
|
-
/**
|
|
2135
|
-
* Mobile UI Example - Showcases the component on smaller screens
|
|
2136
|
-
*
|
|
2137
|
-
* This story demonstrates how AtomixGlass components can be used to create
|
|
2138
|
-
* mobile-friendly interfaces with responsive design and touch interactions.
|
|
2139
|
-
*/
|
|
2140
|
-
export const MobileUIExample: Story = {
|
|
2141
|
-
render: () => {
|
|
2142
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2143
|
-
const [activeTab, setActiveTab] = useState('home');
|
|
2144
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2145
|
-
const [notificationCount, setNotificationCount] = useState(3);
|
|
2146
|
-
|
|
2147
|
-
const handleTabChange = (tab: string) => {
|
|
2148
|
-
setActiveTab(tab);
|
|
2149
|
-
};
|
|
2150
|
-
|
|
2151
|
-
const clearNotifications = () => {
|
|
2152
|
-
setNotificationCount(0);
|
|
2153
|
-
};
|
|
2154
|
-
|
|
2155
|
-
// Mobile device frame styles
|
|
2156
|
-
const phoneFrameStyle = {
|
|
2157
|
-
width: '375px',
|
|
2158
|
-
height: '667px',
|
|
2159
|
-
borderRadius: '36px',
|
|
2160
|
-
padding: '12px',
|
|
2161
|
-
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)',
|
|
2162
|
-
position: 'relative' as const,
|
|
2163
|
-
};
|
|
2164
|
-
|
|
2165
|
-
const phoneScreenStyle = {
|
|
2166
|
-
width: '100%',
|
|
2167
|
-
height: '100%',
|
|
2168
|
-
borderRadius: '24px',
|
|
2169
|
-
position: 'relative' as const,
|
|
2170
|
-
backgroundImage:
|
|
2171
|
-
'url(https://images.unsplash.com/photo-1697231924875-a6eea91b071b?q=80&w=987&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)',
|
|
2172
|
-
backgroundSize: 'cover' as const,
|
|
2173
|
-
backgroundPosition: 'center' as const,
|
|
2174
|
-
overflow: 'hidden',
|
|
2175
|
-
color: 'white',
|
|
2176
|
-
};
|
|
2177
|
-
|
|
2178
|
-
const phoneNotchStyle = {
|
|
2179
|
-
position: 'absolute' as const,
|
|
2180
|
-
top: '0',
|
|
2181
|
-
left: '50%',
|
|
2182
|
-
transform: 'translateX(-50%)',
|
|
2183
|
-
width: '180px',
|
|
2184
|
-
height: '30px',
|
|
2185
|
-
borderBottomLeftRadius: '14px',
|
|
2186
|
-
borderBottomRightRadius: '14px',
|
|
2187
|
-
background: '#000',
|
|
2188
|
-
zIndex: 10,
|
|
2189
|
-
};
|
|
2190
|
-
|
|
2191
|
-
// App content styles
|
|
2192
|
-
const appContentStyle = {
|
|
2193
|
-
height: '100%',
|
|
2194
|
-
display: 'flex',
|
|
2195
|
-
flexDirection: 'column' as const,
|
|
2196
|
-
position: 'relative' as const,
|
|
2197
|
-
};
|
|
2198
|
-
|
|
2199
|
-
const headerStyle = {
|
|
2200
|
-
padding: '50px 20px 15px',
|
|
2201
|
-
display: 'flex',
|
|
2202
|
-
width: '100%',
|
|
2203
|
-
justifyContent: 'space-between',
|
|
2204
|
-
alignItems: 'center',
|
|
2205
|
-
};
|
|
2206
|
-
|
|
2207
|
-
const mainContentStyle = {
|
|
2208
|
-
flex: 1,
|
|
2209
|
-
padding: '0 15px',
|
|
2210
|
-
};
|
|
2211
|
-
|
|
2212
|
-
// Tab content based on active tab
|
|
2213
|
-
const renderTabContent = () => {
|
|
2214
|
-
switch (activeTab) {
|
|
2215
|
-
case 'home':
|
|
2216
|
-
return (
|
|
2217
|
-
<div style={{ padding: '10px 0' }}>
|
|
2218
|
-
<AtomixGlass
|
|
2219
|
-
displacementScale={35}
|
|
2220
|
-
blurAmount={1}
|
|
2221
|
-
saturation={150}
|
|
2222
|
-
aberrationIntensity={1.5}
|
|
2223
|
-
elasticity={0.2}
|
|
2224
|
-
cornerRadius={20}
|
|
2225
|
-
mode="standard"
|
|
2226
|
-
>
|
|
2227
|
-
<div style={{ padding: '20px' }}>
|
|
2228
|
-
<h3 style={{ margin: '0 0 10px 0', fontSize: '18px', color: 'white' }}>
|
|
2229
|
-
Welcome Back
|
|
2230
|
-
</h3>
|
|
2231
|
-
<p
|
|
2232
|
-
style={{
|
|
2233
|
-
margin: '0 0 15px 0',
|
|
2234
|
-
fontSize: '14px',
|
|
2235
|
-
lineHeight: 1.5,
|
|
2236
|
-
color: 'white',
|
|
2237
|
-
}}
|
|
2238
|
-
>
|
|
2239
|
-
Your daily summary and activity feed
|
|
2240
|
-
</p>
|
|
2241
|
-
<div
|
|
2242
|
-
style={{
|
|
2243
|
-
display: 'flex',
|
|
2244
|
-
alignItems: 'center',
|
|
2245
|
-
gap: '10px',
|
|
2246
|
-
marginTop: '15px',
|
|
2247
|
-
}}
|
|
2248
|
-
>
|
|
2249
|
-
<div
|
|
2250
|
-
style={{
|
|
2251
|
-
width: '40px',
|
|
2252
|
-
height: '40px',
|
|
2253
|
-
borderRadius: '50%',
|
|
2254
|
-
background: 'rgba(255,255,255,0.2)',
|
|
2255
|
-
display: 'flex',
|
|
2256
|
-
alignItems: 'center',
|
|
2257
|
-
justifyContent: 'center',
|
|
2258
|
-
fontSize: '18px',
|
|
2259
|
-
}}
|
|
2260
|
-
>
|
|
2261
|
-
👤
|
|
2262
|
-
</div>
|
|
2263
|
-
<div>
|
|
2264
|
-
<div style={{ fontWeight: 500, color: 'white' }}>User Profile</div>
|
|
2265
|
-
<div style={{ fontSize: '12px', opacity: 0.7, color: 'white' }}>
|
|
2266
|
-
View your account
|
|
2267
|
-
</div>
|
|
2268
|
-
</div>
|
|
2269
|
-
</div>
|
|
2270
|
-
</div>
|
|
2271
|
-
</AtomixGlass>
|
|
2272
|
-
|
|
2273
|
-
<div style={{ height: '15px' }} />
|
|
2274
|
-
|
|
2275
|
-
<AtomixGlass
|
|
2276
|
-
displacementScale={30}
|
|
2277
|
-
blurAmount={2}
|
|
2278
|
-
saturation={165}
|
|
2279
|
-
aberrationIntensity={0}
|
|
2280
|
-
elasticity={0.2}
|
|
2281
|
-
cornerRadius={15}
|
|
2282
|
-
mode="standard"
|
|
2283
|
-
>
|
|
2284
|
-
<div style={{ padding: '20px' }}>
|
|
2285
|
-
<h3 style={{ margin: '0 0 15px 0', fontSize: '16px', color: 'white' }}>
|
|
2286
|
-
Recent Activity
|
|
2287
|
-
</h3>
|
|
2288
|
-
{[1, 2, 3].map(item => (
|
|
2289
|
-
<div
|
|
2290
|
-
key={item}
|
|
2291
|
-
style={{
|
|
2292
|
-
padding: '10px 0',
|
|
2293
|
-
borderBottom: item < 3 ? '1px solid rgba(255,255,255,0.1)' : 'none',
|
|
2294
|
-
display: 'flex',
|
|
2295
|
-
alignItems: 'center',
|
|
2296
|
-
gap: '10px',
|
|
2297
|
-
}}
|
|
2298
|
-
>
|
|
2299
|
-
<div
|
|
2300
|
-
style={{
|
|
2301
|
-
width: '32px',
|
|
2302
|
-
height: '32px',
|
|
2303
|
-
borderRadius: '8px',
|
|
2304
|
-
background: 'rgba(255,255,255,0.15)',
|
|
2305
|
-
display: 'flex',
|
|
2306
|
-
alignItems: 'center',
|
|
2307
|
-
justifyContent: 'center',
|
|
2308
|
-
fontSize: '14px',
|
|
2309
|
-
color: 'white',
|
|
2310
|
-
}}
|
|
2311
|
-
>
|
|
2312
|
-
{item === 1 ? '📝' : item === 2 ? '🔔' : '💬'}
|
|
2313
|
-
</div>
|
|
2314
|
-
<div>
|
|
2315
|
-
<div style={{ fontSize: '14px', color: 'white' }}>
|
|
2316
|
-
{item === 1
|
|
2317
|
-
? 'New document created'
|
|
2318
|
-
: item === 2
|
|
2319
|
-
? 'Reminder: Meeting at 3 PM'
|
|
2320
|
-
: 'New message from Sarah'}
|
|
2321
|
-
</div>
|
|
2322
|
-
<div style={{ fontSize: '12px', opacity: 0.7, color: 'white' }}>
|
|
2323
|
-
{item === 1 ? '5 minutes ago' : item === 2 ? '1 hour ago' : '3 hours ago'}
|
|
2324
|
-
</div>
|
|
2325
|
-
</div>
|
|
2326
|
-
</div>
|
|
2327
|
-
))}
|
|
2328
|
-
</div>
|
|
2329
|
-
</AtomixGlass>
|
|
2330
|
-
</div>
|
|
2331
|
-
);
|
|
2332
|
-
case 'search':
|
|
2333
|
-
return (
|
|
2334
|
-
<div style={{ padding: '10px 0' }}>
|
|
2335
|
-
<AtomixGlass
|
|
2336
|
-
displacementScale={40}
|
|
2337
|
-
blurAmount={1}
|
|
2338
|
-
saturation={155}
|
|
2339
|
-
aberrationIntensity={1.8}
|
|
2340
|
-
elasticity={0.13}
|
|
2341
|
-
cornerRadius={15}
|
|
2342
|
-
mode="standard"
|
|
2343
|
-
>
|
|
2344
|
-
<div style={{ padding: '15px' }}>
|
|
2345
|
-
<div
|
|
2346
|
-
style={{
|
|
2347
|
-
display: 'flex',
|
|
2348
|
-
alignItems: 'center',
|
|
2349
|
-
gap: '10px',
|
|
2350
|
-
background: 'rgba(255,255,255,0.1)',
|
|
2351
|
-
borderRadius: '10px',
|
|
2352
|
-
padding: '8px 12px',
|
|
2353
|
-
}}
|
|
2354
|
-
>
|
|
2355
|
-
<span>🔍</span>
|
|
2356
|
-
<input
|
|
2357
|
-
type="text"
|
|
2358
|
-
placeholder="Search..."
|
|
2359
|
-
style={{
|
|
2360
|
-
background: 'transparent',
|
|
2361
|
-
border: 'none',
|
|
2362
|
-
outline: 'none',
|
|
2363
|
-
color: 'white',
|
|
2364
|
-
width: '100%',
|
|
2365
|
-
fontSize: '14px',
|
|
2366
|
-
}}
|
|
2367
|
-
/>
|
|
2368
|
-
</div>
|
|
2369
|
-
</div>
|
|
2370
|
-
</AtomixGlass>
|
|
2371
|
-
|
|
2372
|
-
<div style={{ height: '15px' }} />
|
|
2373
|
-
|
|
2374
|
-
<AtomixGlass
|
|
2375
|
-
displacementScale={15}
|
|
2376
|
-
blurAmount={1}
|
|
2377
|
-
saturation={140}
|
|
2378
|
-
aberrationIntensity={1}
|
|
2379
|
-
cornerRadius={15}
|
|
2380
|
-
>
|
|
2381
|
-
<div style={{ padding: '20px' }}>
|
|
2382
|
-
<h3 style={{ margin: '0 0 15px 0', fontSize: '16px', color: '#fff' }}>
|
|
2383
|
-
Search Categories
|
|
2384
|
-
</h3>
|
|
2385
|
-
<div
|
|
2386
|
-
style={{
|
|
2387
|
-
display: 'grid',
|
|
2388
|
-
gridTemplateColumns: 'repeat(2, 1fr)',
|
|
2389
|
-
gap: '10px',
|
|
2390
|
-
}}
|
|
2391
|
-
>
|
|
2392
|
-
{['Photos', 'Documents', 'Messages', 'Settings'].map(category => (
|
|
2393
|
-
<div
|
|
2394
|
-
key={category}
|
|
2395
|
-
style={{
|
|
2396
|
-
padding: '15px',
|
|
2397
|
-
background: 'rgba(255,255,255,0.1)',
|
|
2398
|
-
borderRadius: '10px',
|
|
2399
|
-
textAlign: 'center',
|
|
2400
|
-
fontSize: '14px',
|
|
2401
|
-
}}
|
|
2402
|
-
>
|
|
2403
|
-
{category}
|
|
2404
|
-
</div>
|
|
2405
|
-
))}
|
|
2406
|
-
</div>
|
|
2407
|
-
</div>
|
|
2408
|
-
</AtomixGlass>
|
|
2409
|
-
</div>
|
|
2410
|
-
);
|
|
2411
|
-
case 'notifications':
|
|
2412
|
-
return (
|
|
2413
|
-
<div style={{ padding: '10px 0' }}>
|
|
2414
|
-
<AtomixGlass
|
|
2415
|
-
displacementScale={50}
|
|
2416
|
-
blurAmount={1}
|
|
2417
|
-
saturation={175}
|
|
2418
|
-
aberrationIntensity={2.2}
|
|
2419
|
-
elasticity={0.14}
|
|
2420
|
-
cornerRadius={15}
|
|
2421
|
-
mode="standard"
|
|
2422
|
-
>
|
|
2423
|
-
<div style={{ padding: '20px' }}>
|
|
2424
|
-
<div
|
|
2425
|
-
style={{
|
|
2426
|
-
display: 'flex',
|
|
2427
|
-
justifyContent: 'space-between',
|
|
2428
|
-
alignItems: 'center',
|
|
2429
|
-
marginBottom: '15px',
|
|
2430
|
-
}}
|
|
2431
|
-
>
|
|
2432
|
-
<h3 style={{ margin: 0, fontSize: '18px', color: 'white' }}>Notifications</h3>
|
|
2433
|
-
<button
|
|
2434
|
-
onClick={clearNotifications}
|
|
2435
|
-
style={{
|
|
2436
|
-
background: 'rgba(255,255,255,0.2)',
|
|
2437
|
-
border: 'none',
|
|
2438
|
-
borderRadius: '5px',
|
|
2439
|
-
padding: '5px 10px',
|
|
2440
|
-
fontSize: '12px',
|
|
2441
|
-
color: 'white',
|
|
2442
|
-
cursor: 'pointer',
|
|
2443
|
-
}}
|
|
2444
|
-
>
|
|
2445
|
-
Clear All
|
|
2446
|
-
</button>
|
|
2447
|
-
</div>
|
|
2448
|
-
|
|
2449
|
-
{notificationCount > 0 ? (
|
|
2450
|
-
Array.from({ length: notificationCount }).map((_, index) => (
|
|
2451
|
-
<div
|
|
2452
|
-
key={index}
|
|
2453
|
-
style={{
|
|
2454
|
-
padding: '12px',
|
|
2455
|
-
background: 'rgba(255,255,255,0.1)',
|
|
2456
|
-
borderRadius: '10px',
|
|
2457
|
-
marginBottom: '10px',
|
|
2458
|
-
}}
|
|
2459
|
-
>
|
|
2460
|
-
<div
|
|
2461
|
-
style={{
|
|
2462
|
-
display: 'flex',
|
|
2463
|
-
alignItems: 'center',
|
|
2464
|
-
gap: '10px',
|
|
2465
|
-
}}
|
|
2466
|
-
>
|
|
2467
|
-
<div
|
|
2468
|
-
style={{
|
|
2469
|
-
width: '36px',
|
|
2470
|
-
height: '36px',
|
|
2471
|
-
borderRadius: '50%',
|
|
2472
|
-
background: 'rgba(255,255,255,0.2)',
|
|
2473
|
-
display: 'flex',
|
|
2474
|
-
alignItems: 'center',
|
|
2475
|
-
justifyContent: 'center',
|
|
2476
|
-
fontSize: '16px',
|
|
2477
|
-
}}
|
|
2478
|
-
>
|
|
2479
|
-
{index === 0 ? '📱' : index === 1 ? '🔔' : '✉️'}
|
|
2480
|
-
</div>
|
|
2481
|
-
<div>
|
|
2482
|
-
<div style={{ fontSize: '14px', fontWeight: 500, color: 'white' }}>
|
|
2483
|
-
{index === 0
|
|
2484
|
-
? 'New Login Detected'
|
|
2485
|
-
: index === 1
|
|
2486
|
-
? 'Calendar Reminder'
|
|
2487
|
-
: 'New Message'}
|
|
2488
|
-
</div>
|
|
2489
|
-
<div style={{ fontSize: '12px', opacity: 0.7, color: 'white' }}>
|
|
2490
|
-
{index === 0
|
|
2491
|
-
? 'A new device logged into your account'
|
|
2492
|
-
: index === 1
|
|
2493
|
-
? 'Meeting with design team in 30 minutes'
|
|
2494
|
-
: 'Sarah sent you a new message'}
|
|
2495
|
-
</div>
|
|
2496
|
-
</div>
|
|
2497
|
-
</div>
|
|
2498
|
-
</div>
|
|
2499
|
-
))
|
|
2500
|
-
) : (
|
|
2501
|
-
<div
|
|
2502
|
-
style={{
|
|
2503
|
-
textAlign: 'center',
|
|
2504
|
-
padding: '30px 0',
|
|
2505
|
-
opacity: 0.7,
|
|
2506
|
-
fontSize: '14px',
|
|
2507
|
-
}}
|
|
2508
|
-
>
|
|
2509
|
-
No new notifications
|
|
2510
|
-
</div>
|
|
2511
|
-
)}
|
|
2512
|
-
</div>
|
|
2513
|
-
</AtomixGlass>
|
|
2514
|
-
</div>
|
|
2515
|
-
);
|
|
2516
|
-
case 'profile':
|
|
2517
|
-
return (
|
|
2518
|
-
<div style={{ padding: '10px 0' }}>
|
|
2519
|
-
<AtomixGlass
|
|
2520
|
-
displacementScale={42}
|
|
2521
|
-
blurAmount={1}
|
|
2522
|
-
saturation={165}
|
|
2523
|
-
aberrationIntensity={2.0}
|
|
2524
|
-
elasticity={0.16}
|
|
2525
|
-
cornerRadius={15}
|
|
2526
|
-
mode="standard"
|
|
2527
|
-
>
|
|
2528
|
-
<div
|
|
2529
|
-
style={{
|
|
2530
|
-
padding: '25px 20px',
|
|
2531
|
-
display: 'flex',
|
|
2532
|
-
flexDirection: 'column',
|
|
2533
|
-
alignItems: 'center',
|
|
2534
|
-
}}
|
|
2535
|
-
>
|
|
2536
|
-
<div
|
|
2537
|
-
style={{
|
|
2538
|
-
width: '80px',
|
|
2539
|
-
height: '80px',
|
|
2540
|
-
borderRadius: '50%',
|
|
2541
|
-
background: 'rgba(255,255,255,0.2)',
|
|
2542
|
-
display: 'flex',
|
|
2543
|
-
alignItems: 'center',
|
|
2544
|
-
justifyContent: 'center',
|
|
2545
|
-
fontSize: '36px',
|
|
2546
|
-
marginBottom: '15px',
|
|
2547
|
-
}}
|
|
2548
|
-
>
|
|
2549
|
-
👤
|
|
2550
|
-
</div>
|
|
2551
|
-
<h3 style={{ margin: '0 0 5px 0', fontSize: '18px', color: 'white' }}>
|
|
2552
|
-
User Name
|
|
2553
|
-
</h3>
|
|
2554
|
-
<p
|
|
2555
|
-
style={{ margin: '0 0 20px 0', fontSize: '14px', opacity: 0.7, color: 'white' }}
|
|
2556
|
-
>
|
|
2557
|
-
user@example.com
|
|
2558
|
-
</p>
|
|
2559
|
-
<button
|
|
2560
|
-
style={{
|
|
2561
|
-
background: 'rgba(255,255,255,0.2)',
|
|
2562
|
-
border: 'none',
|
|
2563
|
-
borderRadius: '8px',
|
|
2564
|
-
padding: '8px 16px',
|
|
2565
|
-
color: 'white',
|
|
2566
|
-
fontSize: '14px',
|
|
2567
|
-
width: '100%',
|
|
2568
|
-
marginBottom: '10px',
|
|
2569
|
-
}}
|
|
2570
|
-
>
|
|
2571
|
-
Edit Profile
|
|
2572
|
-
</button>
|
|
2573
|
-
<button
|
|
2574
|
-
style={{
|
|
2575
|
-
background: 'rgba(255,255,255,0.1)',
|
|
2576
|
-
border: 'none',
|
|
2577
|
-
borderRadius: '8px',
|
|
2578
|
-
padding: '8px 16px',
|
|
2579
|
-
color: 'white',
|
|
2580
|
-
fontSize: '14px',
|
|
2581
|
-
width: '100%',
|
|
2582
|
-
}}
|
|
2583
|
-
>
|
|
2584
|
-
Settings
|
|
2585
|
-
</button>
|
|
2586
|
-
</div>
|
|
2587
|
-
</AtomixGlass>
|
|
2588
|
-
</div>
|
|
2589
|
-
);
|
|
2590
|
-
default:
|
|
2591
|
-
return null;
|
|
2592
|
-
}
|
|
2593
|
-
};
|
|
2594
|
-
|
|
2595
|
-
return (
|
|
2596
|
-
<BackgroundWrapper
|
|
2597
|
-
backgroundImage={'https://images.pexels.com/photos/16702076/pexels-photo-16702076.jpeg'}
|
|
2598
|
-
height="90vh"
|
|
2599
|
-
style={{
|
|
2600
|
-
maxWidth: '1400px',
|
|
2601
|
-
padding: '40px 20px',
|
|
2602
|
-
}}
|
|
2603
|
-
>
|
|
2604
|
-
<div
|
|
2605
|
-
style={{
|
|
2606
|
-
display: 'flex',
|
|
2607
|
-
flexWrap: 'wrap',
|
|
2608
|
-
justifyContent: 'center',
|
|
2609
|
-
}}
|
|
2610
|
-
>
|
|
2611
|
-
<div style={{ maxWidth: '300px' }}>
|
|
2612
|
-
<h2
|
|
2613
|
-
style={{
|
|
2614
|
-
margin: '0 0 20px 0',
|
|
2615
|
-
fontSize: '28px',
|
|
2616
|
-
fontWeight: 500,
|
|
2617
|
-
color: '#ffffff',
|
|
2618
|
-
textShadow: '0 2px 4px rgba(0,0,0,0.2)',
|
|
2619
|
-
}}
|
|
2620
|
-
>
|
|
2621
|
-
Mobile UI Example
|
|
2622
|
-
</h2>
|
|
2623
|
-
|
|
2624
|
-
<p
|
|
2625
|
-
style={{
|
|
2626
|
-
fontSize: '16px',
|
|
2627
|
-
maxWidth: '600px',
|
|
2628
|
-
margin: '0 auto 30px',
|
|
2629
|
-
color: '#ffffff',
|
|
2630
|
-
textShadow: '0 1px 2px rgba(0,0,0,0.2)',
|
|
2631
|
-
}}
|
|
2632
|
-
>
|
|
2633
|
-
AtomixGlass components optimized for mobile interfaces with touch-friendly controls
|
|
2634
|
-
</p>
|
|
2635
|
-
</div>
|
|
2636
|
-
{/* Phone frame */}
|
|
2637
|
-
<div style={phoneFrameStyle}>
|
|
2638
|
-
<div style={phoneScreenStyle}>
|
|
2639
|
-
<div style={phoneNotchStyle} />
|
|
2640
|
-
|
|
2641
|
-
{/* App content */}
|
|
2642
|
-
<div style={appContentStyle}>
|
|
2643
|
-
{/* Header */}
|
|
2644
|
-
<AtomixGlass
|
|
2645
|
-
displacementScale={30}
|
|
2646
|
-
blurAmount={1}
|
|
2647
|
-
saturation={130}
|
|
2648
|
-
aberrationIntensity={1.2}
|
|
2649
|
-
elasticity={0.1}
|
|
2650
|
-
cornerRadius={0}
|
|
2651
|
-
mode="standard"
|
|
2652
|
-
>
|
|
2653
|
-
<div style={headerStyle}>
|
|
2654
|
-
<h2 style={{ margin: 0, fontSize: '18px' }}>
|
|
2655
|
-
{activeTab.charAt(0).toUpperCase() + activeTab.slice(1)}
|
|
2656
|
-
</h2>
|
|
2657
|
-
<div
|
|
2658
|
-
style={{
|
|
2659
|
-
width: '32px',
|
|
2660
|
-
height: '32px',
|
|
2661
|
-
borderRadius: '50%',
|
|
2662
|
-
background: 'rgba(255,255,255,0.1)',
|
|
2663
|
-
display: 'flex',
|
|
2664
|
-
alignItems: 'center',
|
|
2665
|
-
justifyContent: 'center',
|
|
2666
|
-
}}
|
|
2667
|
-
>
|
|
2668
|
-
👤
|
|
2669
|
-
</div>
|
|
2670
|
-
</div>
|
|
2671
|
-
</AtomixGlass>
|
|
2672
|
-
|
|
2673
|
-
{/* Main content area */}
|
|
2674
|
-
<div style={mainContentStyle}>{renderTabContent()}</div>
|
|
2675
|
-
|
|
2676
|
-
{/* Bottom navigation */}
|
|
2677
|
-
<AtomixGlass
|
|
2678
|
-
displacementScale={25}
|
|
2679
|
-
blurAmount={1}
|
|
2680
|
-
saturation={125}
|
|
2681
|
-
aberrationIntensity={1.0}
|
|
2682
|
-
elasticity={0.08}
|
|
2683
|
-
cornerRadius={0}
|
|
2684
|
-
mode="standard"
|
|
2685
|
-
style={{ borderRadius: '0' }}
|
|
2686
|
-
>
|
|
2687
|
-
<div
|
|
2688
|
-
style={{
|
|
2689
|
-
display: 'flex',
|
|
2690
|
-
justifyContent: 'space-around',
|
|
2691
|
-
padding: '15px 0',
|
|
2692
|
-
}}
|
|
2693
|
-
>
|
|
2694
|
-
{[
|
|
2695
|
-
{ id: 'home', icon: '🏠' },
|
|
2696
|
-
{ id: 'search', icon: '🔍' },
|
|
2697
|
-
{ id: 'notifications', icon: '🔔', badge: notificationCount },
|
|
2698
|
-
{ id: 'profile', icon: '👤' },
|
|
2699
|
-
].map(tab => (
|
|
2700
|
-
<div
|
|
2701
|
-
key={tab.id}
|
|
2702
|
-
onClick={() => handleTabChange(tab.id)}
|
|
2703
|
-
style={{
|
|
2704
|
-
display: 'flex',
|
|
2705
|
-
flexDirection: 'column',
|
|
2706
|
-
alignItems: 'center',
|
|
2707
|
-
opacity: activeTab === tab.id ? 1 : 0.6,
|
|
2708
|
-
position: 'relative',
|
|
2709
|
-
cursor: 'pointer',
|
|
2710
|
-
}}
|
|
2711
|
-
>
|
|
2712
|
-
<div style={{ fontSize: '20px' }}>{tab.icon}</div>
|
|
2713
|
-
{tab.badge && tab.badge > 0 && (
|
|
2714
|
-
<div
|
|
2715
|
-
style={{
|
|
2716
|
-
position: 'absolute',
|
|
2717
|
-
top: '-5px',
|
|
2718
|
-
right: '-5px',
|
|
2719
|
-
background: '#ff3b3080',
|
|
2720
|
-
color: 'white',
|
|
2721
|
-
borderRadius: '50%',
|
|
2722
|
-
width: '18px',
|
|
2723
|
-
height: '18px',
|
|
2724
|
-
fontSize: '12px',
|
|
2725
|
-
display: 'flex',
|
|
2726
|
-
alignItems: 'center',
|
|
2727
|
-
justifyContent: 'center',
|
|
2728
|
-
}}
|
|
2729
|
-
>
|
|
2730
|
-
{tab.badge}
|
|
2731
|
-
</div>
|
|
2732
|
-
)}
|
|
2733
|
-
</div>
|
|
2734
|
-
))}
|
|
2735
|
-
</div>
|
|
2736
|
-
</AtomixGlass>
|
|
2737
|
-
</div>
|
|
2738
|
-
</div>
|
|
2739
|
-
</div>
|
|
2740
|
-
</div>
|
|
2741
|
-
</BackgroundWrapper>
|
|
2742
|
-
);
|
|
2743
|
-
},
|
|
2744
|
-
parameters: {
|
|
2745
|
-
docs: {
|
|
2746
|
-
description: {
|
|
2747
|
-
story:
|
|
2748
|
-
'This example demonstrates how AtomixGlass components can be optimized for mobile interfaces. The design showcases a complete mobile app UI with navigation tabs, responsive layouts, and touch-friendly controls. The glass effect provides a modern and elegant look while maintaining excellent readability and usability on smaller screens.',
|
|
2749
|
-
},
|
|
2750
|
-
},
|
|
2751
|
-
},
|
|
2752
|
-
};
|
|
2753
|
-
|
|
2754
|
-
// Theme switching example
|
|
2755
|
-
export const ThemeSwitching: Story = {
|
|
2756
|
-
render: () => {
|
|
2757
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2758
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('dark');
|
|
2759
|
-
|
|
2760
|
-
return (
|
|
2761
|
-
<BackgroundWrapper
|
|
2762
|
-
backgroundImage={
|
|
2763
|
-
theme === 'light'
|
|
2764
|
-
? backgroundImages[6] // Cozy café interior for light theme
|
|
2765
|
-
: backgroundImages[7] // Desert landscape for dark theme
|
|
2766
|
-
}
|
|
2767
|
-
>
|
|
2768
|
-
<div
|
|
2769
|
-
style={{
|
|
2770
|
-
display: 'flex',
|
|
2771
|
-
flexDirection: 'column',
|
|
2772
|
-
alignItems: 'center',
|
|
2773
|
-
justifyContent: 'space-between',
|
|
2774
|
-
gap: '20px',
|
|
2775
|
-
}}
|
|
2776
|
-
>
|
|
2777
|
-
<AtomixGlass
|
|
2778
|
-
displacementScale={60}
|
|
2779
|
-
blurAmount={1}
|
|
2780
|
-
saturation={theme === 'light' ? 120 : 160}
|
|
2781
|
-
aberrationIntensity={2.2}
|
|
2782
|
-
elasticity={0.15}
|
|
2783
|
-
cornerRadius={20}
|
|
2784
|
-
overLight={theme === 'light'}
|
|
2785
|
-
mode="standard"
|
|
2786
|
-
style={{ width: '350px' }}
|
|
2787
|
-
>
|
|
2788
|
-
<div style={{ padding: '25px', textAlign: 'center' }}>
|
|
2789
|
-
<h2 style={{ marginTop: 0 }}>{theme === 'light' ? 'Light Theme' : 'Dark Theme'}</h2>
|
|
2790
|
-
<p>The glass effect adapts to different background themes.</p>
|
|
2791
|
-
<button
|
|
2792
|
-
className={`u-mt-4 c-btn c-btn--${theme === 'light' ? 'primary' : 'outline-light'}`}
|
|
2793
|
-
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
|
|
2794
|
-
>
|
|
2795
|
-
Switch to {theme === 'light' ? 'Dark' : 'Light'} Theme
|
|
2796
|
-
</button>
|
|
2797
|
-
</div>
|
|
2798
|
-
</AtomixGlass>
|
|
2799
|
-
</div>
|
|
2800
|
-
</BackgroundWrapper>
|
|
2801
|
-
);
|
|
2802
|
-
},
|
|
2803
|
-
};
|
|
2804
|
-
|
|
2805
|
-
/**
|
|
2806
|
-
* Video Background Example
|
|
2807
|
-
* Demonstrates the glass effect over a moving video background
|
|
2808
|
-
*/
|
|
2809
|
-
export const VideoBackground: Story = {
|
|
2810
|
-
render: () => {
|
|
2811
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2812
|
-
const [glassSettings, setGlassSettings] = useState({
|
|
2813
|
-
displacementScale: 80,
|
|
2814
|
-
blurAmount: 0,
|
|
2815
|
-
saturation: 150,
|
|
2816
|
-
aberrationIntensity: 0,
|
|
2817
|
-
cornerRadius: 24,
|
|
2818
|
-
mode: 'standard' as const,
|
|
2819
|
-
});
|
|
2820
|
-
|
|
2821
|
-
const updateSettings = (property: string, value: any) => {
|
|
2822
|
-
setGlassSettings(prev => ({
|
|
2823
|
-
...prev,
|
|
2824
|
-
[property]: value,
|
|
2825
|
-
}));
|
|
2826
|
-
};
|
|
2827
|
-
|
|
2828
|
-
return (
|
|
2829
|
-
<div style={{ position: 'relative', height: '80vh', width: '90vw', overflow: 'hidden' }}>
|
|
2830
|
-
{/* Video Background */}
|
|
2831
|
-
<video
|
|
2832
|
-
autoPlay
|
|
2833
|
-
loop
|
|
2834
|
-
muted
|
|
2835
|
-
playsInline
|
|
2836
|
-
style={{
|
|
2837
|
-
position: 'absolute',
|
|
2838
|
-
top: 0,
|
|
2839
|
-
left: 0,
|
|
2840
|
-
width: '100%',
|
|
2841
|
-
height: '100%',
|
|
2842
|
-
objectFit: 'cover',
|
|
2843
|
-
zIndex: -1,
|
|
2844
|
-
}}
|
|
2845
|
-
>
|
|
2846
|
-
<source src={backgrounds.videoBackground} type="video/mp4" />
|
|
2847
|
-
</video>
|
|
2848
|
-
|
|
2849
|
-
{/* Content over video */}
|
|
2850
|
-
<div
|
|
2851
|
-
style={{
|
|
2852
|
-
display: 'flex',
|
|
2853
|
-
alignItems: 'center',
|
|
2854
|
-
justifyContent: 'center',
|
|
2855
|
-
height: '100%',
|
|
2856
|
-
padding: '40px',
|
|
2857
|
-
gap: '40px',
|
|
2858
|
-
flexWrap: 'wrap',
|
|
2859
|
-
}}
|
|
2860
|
-
>
|
|
2861
|
-
{/* Main Glass Card */}
|
|
2862
|
-
<AtomixGlass
|
|
2863
|
-
displacementScale={glassSettings.displacementScale}
|
|
2864
|
-
blurAmount={glassSettings.blurAmount}
|
|
2865
|
-
saturation={glassSettings.saturation}
|
|
2866
|
-
aberrationIntensity={glassSettings.aberrationIntensity}
|
|
2867
|
-
cornerRadius={glassSettings.cornerRadius}
|
|
2868
|
-
mode={glassSettings.mode}
|
|
2869
|
-
style={{ width: '400px', maxWidth: '100%' }}
|
|
2870
|
-
>
|
|
2871
|
-
<div style={{ padding: '32px', textAlign: 'center' }}>
|
|
2872
|
-
<h2 style={{ marginTop: 0, fontSize: '28px', fontWeight: 600, marginBottom: '16px' }}>
|
|
2873
|
-
Glass Over Video
|
|
2874
|
-
</h2>
|
|
2875
|
-
<p style={{ fontSize: '16px', lineHeight: 1.6, marginBottom: '24px', opacity: 0.9 }}>
|
|
2876
|
-
Experience the stunning glass morphism effect overlaid on dynamic video content. The
|
|
2877
|
-
glass element creates a sophisticated focal point while maintaining visual harmony
|
|
2878
|
-
with the moving background.
|
|
2879
|
-
</p>
|
|
2880
|
-
<div
|
|
2881
|
-
style={{
|
|
2882
|
-
display: 'flex',
|
|
2883
|
-
justifyContent: 'center',
|
|
2884
|
-
gap: '12px',
|
|
2885
|
-
flexWrap: 'wrap',
|
|
2886
|
-
}}
|
|
2887
|
-
>
|
|
2888
|
-
<button className="c-btn c-btn--primary">Get Started</button>
|
|
2889
|
-
<button className="c-btn c-btn--outline">Learn More</button>
|
|
2890
|
-
</div>
|
|
2891
|
-
</div>
|
|
2892
|
-
</AtomixGlass>
|
|
2893
|
-
|
|
2894
|
-
{/* Side Control Panel */}
|
|
2895
|
-
<AtomixGlass
|
|
2896
|
-
displacementScale={40}
|
|
2897
|
-
blurAmount={0.06}
|
|
2898
|
-
saturation={120}
|
|
2899
|
-
aberrationIntensity={1.5}
|
|
2900
|
-
cornerRadius={16}
|
|
2901
|
-
mode="standard"
|
|
2902
|
-
style={{ width: '300px', maxWidth: '100%' }}
|
|
2903
|
-
>
|
|
2904
|
-
<div style={{ padding: '24px' }}>
|
|
2905
|
-
<h3 style={{ marginTop: 0, fontSize: '18px', marginBottom: '20px' }}>
|
|
2906
|
-
Live Controls
|
|
2907
|
-
</h3>
|
|
2908
|
-
|
|
2909
|
-
<div style={{ marginBottom: '16px' }}>
|
|
2910
|
-
<label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
|
|
2911
|
-
Displacement: {glassSettings.displacementScale}
|
|
2912
|
-
</label>
|
|
2913
|
-
<input
|
|
2914
|
-
type="range"
|
|
2915
|
-
min="0"
|
|
2916
|
-
max="150"
|
|
2917
|
-
value={glassSettings.displacementScale}
|
|
2918
|
-
onChange={e => updateSettings('displacementScale', parseInt(e.target.value))}
|
|
2919
|
-
style={{ width: '100%', accentColor: '#6366f1' }}
|
|
2920
|
-
/>
|
|
2921
|
-
</div>
|
|
2922
|
-
|
|
2923
|
-
<div style={{ marginBottom: '16px' }}>
|
|
2924
|
-
<label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
|
|
2925
|
-
Blur: {glassSettings.blurAmount}
|
|
2926
|
-
</label>
|
|
2927
|
-
<input
|
|
2928
|
-
type="range"
|
|
2929
|
-
min="0"
|
|
2930
|
-
max="10"
|
|
2931
|
-
step="0.5"
|
|
2932
|
-
value={glassSettings.blurAmount}
|
|
2933
|
-
onChange={e => updateSettings('blurAmount', parseFloat(e.target.value))}
|
|
2934
|
-
style={{ width: '100%', accentColor: '#6366f1' }}
|
|
2935
|
-
/>
|
|
2936
|
-
</div>
|
|
2937
|
-
|
|
2938
|
-
<div style={{ marginBottom: '16px' }}>
|
|
2939
|
-
<label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
|
|
2940
|
-
Saturation: {glassSettings.saturation}%
|
|
2941
|
-
</label>
|
|
2942
|
-
<input
|
|
2943
|
-
type="range"
|
|
2944
|
-
min="50"
|
|
2945
|
-
max="300"
|
|
2946
|
-
value={glassSettings.saturation}
|
|
2947
|
-
onChange={e => updateSettings('saturation', parseInt(e.target.value))}
|
|
2948
|
-
style={{ width: '100%', accentColor: '#6366f1' }}
|
|
2949
|
-
/>
|
|
2950
|
-
</div>
|
|
2951
|
-
|
|
2952
|
-
<div style={{ marginBottom: '16px' }}>
|
|
2953
|
-
<label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
|
|
2954
|
-
Aberration: {glassSettings.aberrationIntensity}
|
|
2955
|
-
</label>
|
|
2956
|
-
<input
|
|
2957
|
-
type="range"
|
|
2958
|
-
min="0"
|
|
2959
|
-
max="5"
|
|
2960
|
-
step="0.1"
|
|
2961
|
-
value={glassSettings.aberrationIntensity}
|
|
2962
|
-
onChange={e => updateSettings('aberrationIntensity', parseFloat(e.target.value))}
|
|
2963
|
-
style={{ width: '100%', accentColor: '#6366f1' }}
|
|
2964
|
-
/>
|
|
2965
|
-
</div>
|
|
2966
|
-
|
|
2967
|
-
<div style={{ marginBottom: '16px' }}>
|
|
2968
|
-
<label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
|
|
2969
|
-
Corner Radius: {glassSettings.cornerRadius}px
|
|
2970
|
-
</label>
|
|
2971
|
-
<input
|
|
2972
|
-
type="range"
|
|
2973
|
-
min="0"
|
|
2974
|
-
max="100"
|
|
2975
|
-
value={glassSettings.cornerRadius}
|
|
2976
|
-
onChange={e => updateSettings('cornerRadius', parseInt(e.target.value))}
|
|
2977
|
-
style={{ width: '100%', accentColor: '#6366f1' }}
|
|
2978
|
-
/>
|
|
2979
|
-
</div>
|
|
2980
|
-
|
|
2981
|
-
<button
|
|
2982
|
-
className="c-btn c-btn--secondary"
|
|
2983
|
-
style={{ width: '100%' }}
|
|
2984
|
-
onClick={() => {
|
|
2985
|
-
setGlassSettings({
|
|
2986
|
-
displacementScale: 80,
|
|
2987
|
-
blurAmount: 0.08,
|
|
2988
|
-
saturation: 150,
|
|
2989
|
-
aberrationIntensity: 2.5,
|
|
2990
|
-
cornerRadius: 24,
|
|
2991
|
-
mode: 'standard',
|
|
2992
|
-
});
|
|
2993
|
-
}}
|
|
2994
|
-
>
|
|
2995
|
-
Reset Defaults
|
|
2996
|
-
</button>
|
|
2997
|
-
</div>
|
|
2998
|
-
</AtomixGlass>
|
|
2999
|
-
</div>
|
|
3000
|
-
</div>
|
|
3001
|
-
);
|
|
3002
|
-
},
|
|
3003
|
-
parameters: {
|
|
3004
|
-
docs: {
|
|
3005
|
-
description: {
|
|
3006
|
-
story:
|
|
3007
|
-
'This example showcases the AtomixGlass component over a dynamic video background, demonstrating how the glass effect creates stunning visual hierarchy and focus over moving content. Use the live controls to experiment with different settings and see how they affect the glass appearance in real-time.',
|
|
3008
|
-
},
|
|
3009
|
-
},
|
|
3010
|
-
},
|
|
3011
|
-
};
|