app-studio 0.5.73 → 0.5.79
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 +815 -0
- package/dist/app-studio.cjs.development.js +182 -141
- package/dist/app-studio.cjs.development.js.map +1 -1
- package/dist/app-studio.cjs.production.min.js +1 -1
- package/dist/app-studio.esm.js +183 -142
- package/dist/app-studio.esm.js.map +1 -1
- package/dist/app-studio.umd.development.js +180 -139
- package/dist/app-studio.umd.development.js.map +1 -1
- package/dist/app-studio.umd.production.min.js +1 -1
- package/dist/element/Element.d.ts +2 -1
- package/dist/providers/Theme.d.ts +15 -9
- package/dist/utils/colors.d.ts +1 -12
- package/package.json +3 -1
package/README.md
ADDED
|
@@ -0,0 +1,815 @@
|
|
|
1
|
+
# App-Studio
|
|
2
|
+
|
|
3
|
+
App-Studio is a React library designed to streamline the development of modern web applications. It provides a comprehensive suite of reusable components, hooks, utilities, and built-in systems for theming, responsive design, animation, and analytics. Built upon a flexible `Element` base component, App-Studio empowers developers to build high-quality, efficient, and scalable projects faster.
|
|
4
|
+
|
|
5
|
+
## Key Features
|
|
6
|
+
|
|
7
|
+
* **Core `Element` Component:** A versatile base for all UI elements, offering extensive styling via props, including responsive (`media`) and state-based (`on`) styles.
|
|
8
|
+
* **Rich Component Library:** Includes components for layout (`View`, `Horizontal`, `Vertical`, etc.), text (`Text`), images (`Image`, `ImageBackground`), forms (`Form`, `Input`, `Button`), and loading states (`Skeleton`).
|
|
9
|
+
* **Powerful Styling:** Utilizes a utility-prop system for direct styling, alongside support for standard CSS and the `css` prop.
|
|
10
|
+
* **Integrated Theming:** `ThemeProvider` and `useTheme` hook for managing light/dark modes, custom color palettes, and consistent design tokens.
|
|
11
|
+
* **Responsive Design:** `ResponsiveProvider` and `useResponsive` hook provide tools to adapt layouts and styles based on screen size and orientation.
|
|
12
|
+
* **Animation System:** A declarative `Animation` object for easily applying and sequencing CSS animations and transitions, including scroll-driven effects.
|
|
13
|
+
* **Helpful Hooks:** A collection of hooks for managing state, detecting interactions (`useHover`, `useActive`, `useFocus`), tracking viewport status (`useInView`, `useOnScreen`), handling events (`useClickOutside`, `useKeyPress`), and more.
|
|
14
|
+
* **Analytics Integration:** `AnalyticsProvider` to easily integrate event tracking.
|
|
15
|
+
* **TypeScript Support:** Fully typed for a better development experience.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Installation
|
|
20
|
+
|
|
21
|
+
Get started with App-Studio by installing it via npm and setting up the necessary providers in your application root.
|
|
22
|
+
|
|
23
|
+
**Prerequisites**
|
|
24
|
+
|
|
25
|
+
* Node.js (>= 14.x recommended)
|
|
26
|
+
* React (>= 17.x recommended)
|
|
27
|
+
|
|
28
|
+
**Installation Steps**
|
|
29
|
+
|
|
30
|
+
1. Install the package using npm or yarn:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install --save app-studio
|
|
34
|
+
# or
|
|
35
|
+
yarn add app-studio
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. Wrap your application with the core providers. Typically, you'll need `ThemeProvider`, `ResponsiveProvider`, and potentially `AnalyticsProvider` and `WindowSizeProvider`.
|
|
39
|
+
|
|
40
|
+
```jsx
|
|
41
|
+
import React from 'react';
|
|
42
|
+
import {
|
|
43
|
+
ThemeProvider,
|
|
44
|
+
ResponsiveProvider,
|
|
45
|
+
AnalyticsProvider,
|
|
46
|
+
WindowSizeProvider
|
|
47
|
+
} from 'app-studio';
|
|
48
|
+
|
|
49
|
+
// Example analytics tracking function
|
|
50
|
+
const trackMyAppEvent = ({ type, target, ...event }) => {
|
|
51
|
+
console.log('Tracking Event:', { type, target, ...event });
|
|
52
|
+
// Replace with your actual analytics service call, e.g.,
|
|
53
|
+
// YourAnalyticsService.track(`${type}_${target || 'element'}`, event);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function App() {
|
|
57
|
+
return (
|
|
58
|
+
<ThemeProvider> {/* Manages theming (colors, modes) */}
|
|
59
|
+
<ResponsiveProvider> {/* Manages responsive breakpoints and device info */}
|
|
60
|
+
<WindowSizeProvider> {/* Tracks window dimensions */}
|
|
61
|
+
<AnalyticsProvider trackEvent={trackMyAppEvent}> {/* Optional: Enables analytics tracking */}
|
|
62
|
+
{/* Your application components go here */}
|
|
63
|
+
{/* e.g., <YourMainAppComponent /> */}
|
|
64
|
+
</AnalyticsProvider>
|
|
65
|
+
</WindowSizeProvider>
|
|
66
|
+
</ResponsiveProvider>
|
|
67
|
+
</ThemeProvider>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default App;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
# Core Concepts
|
|
77
|
+
|
|
78
|
+
## Element Component
|
|
79
|
+
|
|
80
|
+
The `Element` component is the cornerstone of App-Studio. Most other components extend `Element`. It acts as a highly configurable primitive that renders an HTML tag (defaulting to `div`, configurable via the `as` prop) and accepts a wide range of props for styling.
|
|
81
|
+
|
|
82
|
+
* **Direct Styling Props:** Apply CSS styles directly (e.g., `backgroundColor="blue"`, `padding={10}`).
|
|
83
|
+
* **Responsive Styles:** Use the `media` prop to define styles for specific breakpoints (e.g., `media={{ mobile: { padding: 8 }, desktop: { padding: 16 } }}`).
|
|
84
|
+
* **State-Based Styles:** Use the `on` prop to apply styles based on interaction states like hover, focus, or active (e.g., `on={{ hover: { backgroundColor: 'lightgray' } }}`).
|
|
85
|
+
* **Animation:** Integrates with the animation system via the `animate` prop.
|
|
86
|
+
* **Theming:** Automatically resolves theme colors (e.g., `color="theme.primary"`).
|
|
87
|
+
|
|
88
|
+
## Utility-First Styling
|
|
89
|
+
|
|
90
|
+
App-Studio generates CSS utility classes based on the props you provide to `Element` and its derived components. This approach keeps styles co-located with the component logic and optimizes performance by reusing generated classes.
|
|
91
|
+
|
|
92
|
+
## Theming
|
|
93
|
+
|
|
94
|
+
Use `ThemeProvider` to define global theme settings, including light/dark mode colors and custom theme tokens (e.g., `primary`, `secondary`). The `useTheme` hook provides access to the current theme mode (`themeMode`), theme configuration (`theme`), a function to switch modes (`setThemeMode`), and the essential `getColor` function to resolve color strings (like `color.blue.500` or `theme.primary`) into actual CSS color values for the current mode.
|
|
95
|
+
|
|
96
|
+
## Responsiveness
|
|
97
|
+
|
|
98
|
+
Wrap your app in `ResponsiveProvider` (optionally configuring custom `breakpoints` and `devices`). Use the `useResponsive` hook to access the current breakpoint (`screen`), device type (`currentDevice`), orientation, and helper functions (`on`, `is`) to conditionally render components or apply styles. You can also use the `media` prop on `Element` components for responsive styling.
|
|
99
|
+
|
|
100
|
+
## Animation System
|
|
101
|
+
|
|
102
|
+
App-Studio includes a powerful animation system accessible via the `Animation` object. Apply pre-defined animations (`Animation.fadeIn`, `Animation.slideInLeft`, etc.) or create custom keyframe animations using the `animate` prop on any `Element`-based component. Animations can be sequenced, triggered by events (`on` prop), or applied responsively (`media` prop).
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
# Components
|
|
107
|
+
|
|
108
|
+
App-Studio provides a set of reusable components built on the `Element` base.
|
|
109
|
+
|
|
110
|
+
## Element
|
|
111
|
+
|
|
112
|
+
The fundamental building block. Renders as a specified HTML tag (`as` prop, defaults to `div`) and accepts extensive styling props.
|
|
113
|
+
|
|
114
|
+
**Key Props:**
|
|
115
|
+
|
|
116
|
+
| Prop | Type | Description |
|
|
117
|
+
| :-------- | :------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `as` | `keyof JSX.IntrinsicElements` | HTML element tag to render (default: 'div'). |
|
|
119
|
+
| `style` | `CSSProperties` | Standard React style object. |
|
|
120
|
+
| `css` | `CSSProperties` or `string` | Apply custom CSS styles or raw CSS strings. |
|
|
121
|
+
| `media` | `Record<string, CssProps>` | Defines styles for specific breakpoints or devices (e.g., `mobile`, `tablet`, `lg`). |
|
|
122
|
+
| `on` | `Record<string, CssProps>` | Defines styles for interaction states (e.g., `hover`, `focus`, `active`). Includes `animate` support here. |
|
|
123
|
+
| `animate` | `AnimationProps` or `AnimationProps[]` | Applies one or more animations from the `Animation` system. |
|
|
124
|
+
| `size` | `number` or `string` | Sets equal `width` and `height`. |
|
|
125
|
+
| `shadow` | `boolean` or `number` | Applies a pre-defined box-shadow effect (levels 0-9). |
|
|
126
|
+
| `...rest` | `CssProps` | Accepts numerous CSS properties directly as props (e.g., `backgroundColor`, `padding`, `fontSize`, etc.). |
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
**Example:**
|
|
131
|
+
|
|
132
|
+
```jsx
|
|
133
|
+
import { Element } from 'app-studio';
|
|
134
|
+
|
|
135
|
+
function MyStyledElement() {
|
|
136
|
+
return (
|
|
137
|
+
<Element
|
|
138
|
+
as="section"
|
|
139
|
+
padding={16}
|
|
140
|
+
backgroundColor="color.blue.500"
|
|
141
|
+
borderRadius={8}
|
|
142
|
+
color="color.white"
|
|
143
|
+
on={{ hover: { backgroundColor: 'color.blue.600' } }}
|
|
144
|
+
media={{ mobile: { padding: 8 } }}
|
|
145
|
+
>
|
|
146
|
+
This is a styled section.
|
|
147
|
+
</Element>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
In addition to global theming via `ThemeProvider`, the `Element` component offers granular control through the `themeMode`, `colors`, and `theme` props. When specified, these props locally override the context provided by `ThemeProvider` for this specific element instance and how its style props (like `backgroundColor="theme.primary"` or `color="color.blue.500"`) resolve color values. `themeMode` forces 'light' or 'dark' mode resolution, `colors` provides a custom `{ main, palette }` object, and `theme` supplies custom token mappings (e.g., `{ primary: 'color.purple.500' }`). This allows creating distinctly styled sections or components without altering the global theme, useful for sidebars, specific UI states, or component variations.
|
|
153
|
+
|
|
154
|
+
**Example (Local Theme Override):**
|
|
155
|
+
|
|
156
|
+
```jsx
|
|
157
|
+
import { Element, Text } from 'app-studio';
|
|
158
|
+
import { defaultDarkPalette, defaultDarkColors } from 'app-studio/utils/colors'; // Assuming you export these
|
|
159
|
+
|
|
160
|
+
function LocallyThemedSection() {
|
|
161
|
+
// Assume the global theme is currently 'light' mode.
|
|
162
|
+
|
|
163
|
+
// Define a local override theme and colors for this specific section
|
|
164
|
+
const localThemeOverride = { primary: 'color.orange.500', secondary: 'color.teal.300' };
|
|
165
|
+
const localDarkColorsOverride = { main: defaultDarkColors, palette: defaultDarkPalette }; // Using defaults for demonstration
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<Element
|
|
169
|
+
padding={20}
|
|
170
|
+
marginVertical={10}
|
|
171
|
+
// Force dark mode and provide specific theme/color definitions JUST for this Element
|
|
172
|
+
themeMode="dark"
|
|
173
|
+
theme={localThemeOverride}
|
|
174
|
+
colors={localDarkColorsOverride}
|
|
175
|
+
// Styles below will resolve using the LOCAL dark theme override defined above:
|
|
176
|
+
backgroundColor="theme.secondary" // Resolves to 'color.teal.300' via localThemeOverride in dark mode
|
|
177
|
+
border={`3px solid theme.primary`} // Resolves to 'color.orange.500' via localThemeOverride
|
|
178
|
+
borderRadius={8}
|
|
179
|
+
>
|
|
180
|
+
<Text color="color.white"> {/* 'color.white' from localDarkColorsOverride.main */}
|
|
181
|
+
This section forces dark mode with an orange primary, even if the app is light.
|
|
182
|
+
</Text>
|
|
183
|
+
<Element marginTop={8} padding={10} backgroundColor="color.gray.700"> {/* Uses local dark palette */}
|
|
184
|
+
<Text color="theme.primary">Nested Primary (Orange)</Text> {/* Still uses local override */}
|
|
185
|
+
</Element>
|
|
186
|
+
</Element>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## View
|
|
192
|
+
|
|
193
|
+
A versatile container component extending `Element`, primarily used for layout. Defaults to `div`.
|
|
194
|
+
|
|
195
|
+
**Key Features:**
|
|
196
|
+
|
|
197
|
+
* Inherits all `Element` props.
|
|
198
|
+
* Ideal for structuring UI and applying layout styles (Flexbox, Grid).
|
|
199
|
+
|
|
200
|
+
**Variants:**
|
|
201
|
+
|
|
202
|
+
* `Horizontal`: A `View` with `display: flex`, `flexDirection: row`.
|
|
203
|
+
* `Vertical`: A `View` with `display: flex`, `flexDirection: column`.
|
|
204
|
+
* `HorizontalResponsive`: Switches from `row` to `column` on `mobile`.
|
|
205
|
+
* `VerticalResponsive`: Switches from `column` to `row` on `mobile`.
|
|
206
|
+
* `Scroll`: Basic scrollable view (might need explicit overflow styles).
|
|
207
|
+
* `SafeArea`: A view with `overflow: auto`.
|
|
208
|
+
* `Div`, `Span`: Aliases for `Element` rendering `div` and `span` respectively.
|
|
209
|
+
|
|
210
|
+
**Example:**
|
|
211
|
+
|
|
212
|
+
```jsx
|
|
213
|
+
import { View, Horizontal, Text } from 'app-studio';
|
|
214
|
+
|
|
215
|
+
function MyLayout() {
|
|
216
|
+
return (
|
|
217
|
+
<View padding={16} backgroundColor="color.gray.100">
|
|
218
|
+
<Horizontal gap={8} alignItems="center">
|
|
219
|
+
<View width={50} height={50} backgroundColor="color.red.500" borderRadius="50%" />
|
|
220
|
+
<Text fontSize="lg" fontWeight="bold">Item Title</Text>
|
|
221
|
+
</Horizontal>
|
|
222
|
+
</View>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Text
|
|
228
|
+
|
|
229
|
+
A component for rendering text content, extending `Element`. Defaults to `span`.
|
|
230
|
+
|
|
231
|
+
**Key Features:**
|
|
232
|
+
|
|
233
|
+
* Inherits all `Element` props.
|
|
234
|
+
* Applies typography styles easily (`fontSize`, `fontWeight`, `lineHeight`, `textAlign`, etc.).
|
|
235
|
+
* Supports `toUpperCase` prop.
|
|
236
|
+
|
|
237
|
+
**Key Props (in addition to Element props):**
|
|
238
|
+
|
|
239
|
+
| Prop | Type | Description |
|
|
240
|
+
| :------------ | :-------- | :---------------------------------- |
|
|
241
|
+
| `as` | `string` | HTML element tag (default: 'span'). |
|
|
242
|
+
| `toUpperCase` | `boolean` | Converts text content to uppercase. |
|
|
243
|
+
| `...rest` | `CssProps` | Typography props like `fontSize`, `fontWeight`, `color`, etc. |
|
|
244
|
+
|
|
245
|
+
**Example:**
|
|
246
|
+
|
|
247
|
+
```jsx
|
|
248
|
+
import { Text } from 'app-studio';
|
|
249
|
+
|
|
250
|
+
function MyText() {
|
|
251
|
+
return (
|
|
252
|
+
<Text
|
|
253
|
+
fontSize="xl"
|
|
254
|
+
fontWeight="bold"
|
|
255
|
+
color="theme.primary"
|
|
256
|
+
textAlign="center"
|
|
257
|
+
toUpperCase
|
|
258
|
+
>
|
|
259
|
+
Important Heading
|
|
260
|
+
</Text>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Image
|
|
266
|
+
|
|
267
|
+
An optimized image component extending `Element`. Renders an `<img>` tag.
|
|
268
|
+
|
|
269
|
+
**Key Features:**
|
|
270
|
+
|
|
271
|
+
* Inherits `Element` props relevant to images.
|
|
272
|
+
* Supports standard `src`, `alt` attributes.
|
|
273
|
+
* Potentially supports features like lazy loading or fallbacks (verify implementation specifics if needed).
|
|
274
|
+
|
|
275
|
+
**Key Props (in addition to relevant Element props):**
|
|
276
|
+
|
|
277
|
+
| Prop | Type | Description |
|
|
278
|
+
| :-------- | :------- | :---------------------------------------------- |
|
|
279
|
+
| `src` | `string` | Image source URL. |
|
|
280
|
+
| `alt` | `string` | Alternative text for accessibility. |
|
|
281
|
+
| `...rest` | `CssProps` | Styling props like `width`, `height`, `borderRadius`, `objectFit`. |
|
|
282
|
+
|
|
283
|
+
**Variant:**
|
|
284
|
+
|
|
285
|
+
* `ImageBackground`: Renders an `Element` (`div`) with the image applied as a `backgroundImage` (covers and no-repeat). Takes `src` prop.
|
|
286
|
+
|
|
287
|
+
**Example:**
|
|
288
|
+
|
|
289
|
+
```jsx
|
|
290
|
+
import { Image, ImageBackground, Text } from 'app-studio';
|
|
291
|
+
|
|
292
|
+
function MyImage() {
|
|
293
|
+
return (
|
|
294
|
+
<>
|
|
295
|
+
<Image src="logo.png" alt="Company Logo" width={100} height={50} objectFit="contain" />
|
|
296
|
+
|
|
297
|
+
<ImageBackground src="hero.jpg" height={200} width="100%" display="flex" alignItems="center" justifyContent="center">
|
|
298
|
+
<Text color="color.white" fontSize="2xl">Overlay Text</Text>
|
|
299
|
+
</ImageBackground>
|
|
300
|
+
</>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Form
|
|
306
|
+
|
|
307
|
+
Simplifies form creation and handling. Extends `Element` and renders a `<form>` tag.
|
|
308
|
+
|
|
309
|
+
**Key Features:**
|
|
310
|
+
|
|
311
|
+
* Inherits `Element` props.
|
|
312
|
+
* Handles form submission via `onSubmit`.
|
|
313
|
+
* Includes styled sub-components `Form.Input` and `Form.Button`.
|
|
314
|
+
|
|
315
|
+
**Sub-components:**
|
|
316
|
+
|
|
317
|
+
* `Input`: Extends `Element`, renders an `<input>` tag. Accepts standard input attributes (`name`, `type`, `placeholder`, `value`, `onChange`, etc.) and styling props.
|
|
318
|
+
* `Button`: Extends `Element`, renders a `<button>` tag. Accepts standard button attributes (`type`, `disabled`, etc.) and styling props. Handles `onClick`.
|
|
319
|
+
|
|
320
|
+
**Key Props (Form):**
|
|
321
|
+
|
|
322
|
+
| Prop | Type | Description |
|
|
323
|
+
| :--------- | :--------- | :---------------------------------------- |
|
|
324
|
+
| `onSubmit` | `function` | Callback function executed on submission. |
|
|
325
|
+
| `...rest` | `CssProps` | Styling props for the form container. |
|
|
326
|
+
|
|
327
|
+
**Example:**
|
|
328
|
+
|
|
329
|
+
```jsx
|
|
330
|
+
import { Form, Input, Button } from 'app-studio';
|
|
331
|
+
|
|
332
|
+
function MyForm() {
|
|
333
|
+
const handleSubmit = (event) => {
|
|
334
|
+
event.preventDefault();
|
|
335
|
+
const formData = new FormData(event.target);
|
|
336
|
+
const data = Object.fromEntries(formData.entries());
|
|
337
|
+
console.log('Form Data:', data);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
return (
|
|
341
|
+
<Form onSubmit={handleSubmit} display="flex" flexDirection="column" gap={12}>
|
|
342
|
+
<Input name="username" placeholder="Username" padding={8} borderRadius={4} border="1px solid color.gray.300" />
|
|
343
|
+
<Input name="password" type="password" placeholder="Password" padding={8} borderRadius={4} border="1px solid color.gray.300" />
|
|
344
|
+
<Button type="submit" backgroundColor="color.blue.500" color="color.white" padding={10} borderRadius={4} cursor="pointer">
|
|
345
|
+
Log In
|
|
346
|
+
</Button>
|
|
347
|
+
</Form>
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Skeleton
|
|
353
|
+
|
|
354
|
+
Displays a placeholder loading state, often with a shimmer animation. Extends `View`.
|
|
355
|
+
|
|
356
|
+
**Key Props (in addition to View props):**
|
|
357
|
+
|
|
358
|
+
| Prop | Type | Default | Description |
|
|
359
|
+
| :--------------- | :----------------- | :--------- | :------------------------------------------- |
|
|
360
|
+
| `width` | `string \| number` | `100%` | Width of the skeleton placeholder. |
|
|
361
|
+
| `height` | `string \| number` | `20px` | Height of the skeleton placeholder. |
|
|
362
|
+
| `duration` | `string` | `'2s'` | Duration of the shimmer animation. |
|
|
363
|
+
| `timingFunction` | `string` | `'linear'` | Timing function of the shimmer animation. |
|
|
364
|
+
| `iterationCount` | `string \| number` | `infinite` | How many times the shimmer animation repeats. |
|
|
365
|
+
|
|
366
|
+
**Example:**
|
|
367
|
+
|
|
368
|
+
```jsx
|
|
369
|
+
import { Skeleton } from 'app-studio';
|
|
370
|
+
|
|
371
|
+
function UserProfileLoading() {
|
|
372
|
+
return (
|
|
373
|
+
<View display="flex" alignItems="center" gap={12}>
|
|
374
|
+
<Skeleton width={50} height={50} borderRadius="50%" />
|
|
375
|
+
<View flex={1} display="flex" flexDirection="column" gap={8}>
|
|
376
|
+
<Skeleton height={20} width="60%" />
|
|
377
|
+
<Skeleton height={16} width="80%" />
|
|
378
|
+
</View>
|
|
379
|
+
</View>
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
# Animation System
|
|
387
|
+
|
|
388
|
+
App-Studio provides a powerful and declarative way to add animations using the `Animation` object and the `animate` prop on `Element`-based components.
|
|
389
|
+
|
|
390
|
+
**Basic Usage**
|
|
391
|
+
|
|
392
|
+
Import the `Animation` object and pass animation configurations to the `animate` prop.
|
|
393
|
+
|
|
394
|
+
```jsx
|
|
395
|
+
import { View, Animation } from 'app-studio';
|
|
396
|
+
|
|
397
|
+
function AnimatedComponent() {
|
|
398
|
+
return (
|
|
399
|
+
<View
|
|
400
|
+
animate={Animation.fadeIn({ duration: '0.5s' })}
|
|
401
|
+
padding={20}
|
|
402
|
+
backgroundColor="color.blue.200"
|
|
403
|
+
>
|
|
404
|
+
Fades In
|
|
405
|
+
</View>
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Event-Based Animations**
|
|
411
|
+
|
|
412
|
+
Trigger animations on interaction states using the `on` prop.
|
|
413
|
+
|
|
414
|
+
```jsx
|
|
415
|
+
import { Button, Animation } from 'app-studio';
|
|
416
|
+
|
|
417
|
+
function HoverButton() {
|
|
418
|
+
return (
|
|
419
|
+
<Button
|
|
420
|
+
padding={10}
|
|
421
|
+
on={{
|
|
422
|
+
hover: {
|
|
423
|
+
animate: Animation.pulse({ duration: '1s', iterationCount: 'infinite' })
|
|
424
|
+
}
|
|
425
|
+
}}
|
|
426
|
+
>
|
|
427
|
+
Hover Over Me
|
|
428
|
+
</Button>
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**Animation Sequences**
|
|
434
|
+
|
|
435
|
+
Pass an array of animation configurations to the `animate` prop to create sequences. Delays are automatically calculated based on previous animation durations and delays.
|
|
436
|
+
|
|
437
|
+
```jsx
|
|
438
|
+
import { View, Animation } from 'app-studio';
|
|
439
|
+
|
|
440
|
+
function SequencedAnimation() {
|
|
441
|
+
const sequence = [
|
|
442
|
+
Animation.fadeIn({ duration: '1s' }), // Fades in over 1s
|
|
443
|
+
Animation.slideInRight({ duration: '0.5s', delay: '0.2s' }) // Slides in 0.2s after fade-in finishes
|
|
444
|
+
];
|
|
445
|
+
|
|
446
|
+
return (
|
|
447
|
+
<View
|
|
448
|
+
animate={sequence}
|
|
449
|
+
padding={20}
|
|
450
|
+
backgroundColor="color.green.200"
|
|
451
|
+
>
|
|
452
|
+
Sequence
|
|
453
|
+
</View>
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Available Animations (`Animation.*`)**
|
|
459
|
+
|
|
460
|
+
A wide range of pre-defined animations are available (check `element/Animation.tsx` for the full list and options):
|
|
461
|
+
|
|
462
|
+
* **Fades:** `fadeIn`, `fadeOut`, `fadeInDown`, `fadeInUp`, etc.
|
|
463
|
+
* **Slides:** `slideInLeft`, `slideInRight`, `slideOutLeft`, `slideOutRight`, etc.
|
|
464
|
+
* **Zooms:** `zoomIn`, `zoomOut`, `zoomInDown`, etc.
|
|
465
|
+
* **Bounces:** `bounce`, `bounceIn`, `bounceOut`.
|
|
466
|
+
* **Rotations:** `rotate`, `flip`, `flipInX`, `flipInY`.
|
|
467
|
+
* **Attention Seekers:** `pulse`, `shake`, `swing`, `tada`, `jello`, `heartBeat`, `headShake`, `wobble`, `flash`.
|
|
468
|
+
* **Special Effects:** `shimmer`, `lightSpeedIn`, `lightSpeedOut`, `hinge`, `jackInTheBox`, `rollIn`, `rollOut`.
|
|
469
|
+
* **Scroll-Driven:** `fadeInScroll`, `slideInLeftScroll`, `scaleDownScroll`, etc. (These often require specific CSS setups like `animation-timeline`).
|
|
470
|
+
|
|
471
|
+
**Animation Properties**
|
|
472
|
+
|
|
473
|
+
Each animation function accepts an options object:
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
interface AnimationProps {
|
|
477
|
+
from?: CSSProperties | any; // Starting styles (for keyframes)
|
|
478
|
+
to?: CSSProperties | any; // Ending styles (for keyframes)
|
|
479
|
+
'0%'?: CSSProperties | any; // Specific keyframe styles
|
|
480
|
+
// ... other percentage keys like '50%'
|
|
481
|
+
duration?: string; // e.g., '1s', '500ms'
|
|
482
|
+
timingFunction?: string; // e.g., 'ease', 'linear', 'ease-in-out', 'steps(N)'
|
|
483
|
+
delay?: string; // e.g., '0.2s', '100ms'
|
|
484
|
+
iterationCount?: string | number; // e.g., '1', 'infinite'
|
|
485
|
+
direction?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
|
|
486
|
+
fillMode?: 'none' | 'forwards' | 'backwards' | 'both';
|
|
487
|
+
playState?: 'running' | 'paused';
|
|
488
|
+
timeline?: string; // For scroll-driven animations (e.g., 'scroll()', 'view()', '--custom-timeline')
|
|
489
|
+
range?: string; // For scroll-driven animations (e.g., 'cover 0% cover 50%', 'entry', 'exit')
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Responsive Animations**
|
|
494
|
+
|
|
495
|
+
Combine `animate` with the `media` prop for different animations on different screen sizes.
|
|
496
|
+
|
|
497
|
+
```jsx
|
|
498
|
+
import { View, Animation } from 'app-studio';
|
|
499
|
+
|
|
500
|
+
function ResponsiveAnimation() {
|
|
501
|
+
return (
|
|
502
|
+
<View
|
|
503
|
+
padding={20}
|
|
504
|
+
backgroundColor="color.purple.200"
|
|
505
|
+
media={{
|
|
506
|
+
mobile: {
|
|
507
|
+
animate: Animation.fadeIn({ duration: '1s' })
|
|
508
|
+
},
|
|
509
|
+
tablet: {
|
|
510
|
+
animate: Animation.slideInLeft({ duration: '0.8s' })
|
|
511
|
+
}
|
|
512
|
+
}}
|
|
513
|
+
>
|
|
514
|
+
Responsive Animation
|
|
515
|
+
</View>
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
# Hooks
|
|
523
|
+
|
|
524
|
+
App-Studio provides hooks for common UI logic and state management needs.
|
|
525
|
+
|
|
526
|
+
*(Note: Descriptions below are based on the provided code structure. Verify specific usage details.)*
|
|
527
|
+
|
|
528
|
+
| Hook | Returns | Description |
|
|
529
|
+
| :---------------- | :-------------- | :--------------------------------------------------------------------- |
|
|
530
|
+
| `useActive` | `[ref, boolean]` | Detects if the referenced element is active (pressed/touched). |
|
|
531
|
+
| `useClickOutside` | `[ref, boolean]` | Detects if a click occurred outside the referenced element. |
|
|
532
|
+
| `useFocus` | `[ref, boolean]` | Tracks the focus state of the referenced element. |
|
|
533
|
+
| `useHover` | `[ref, boolean]` | Detects if the mouse cursor is hovering over the referenced element. |
|
|
534
|
+
| `useInView` | `{ ref, inView }`| Detects if the referenced element is within the viewport using `IntersectionObserver`. Options allow `triggerOnce`. |
|
|
535
|
+
| `useKeyPress` | `boolean` | Takes a `targetKey` string and returns `true` if that key is currently pressed. |
|
|
536
|
+
| `useMount` | `void` | Takes a callback function and runs it once when the component mounts. |
|
|
537
|
+
| `useOnScreen` | `[ref, boolean]` | Similar to `useInView`, detects if the referenced element is on screen using `IntersectionObserver`. |
|
|
538
|
+
| `useResponsive` | `ScreenConfig & { on: func, is: func }` | Provides screen size (`screen`), device (`currentDevice`), orientation, and helper functions (`on`, `is`) to check against breakpoints/devices. |
|
|
539
|
+
| `useScroll` | `ScrollPosition` | Tracks scroll position (`x`, `y`) and progress (`xProgress`, `yProgress`) of the window or a specified container. Options include `throttleMs`, `container`, `offset`. |
|
|
540
|
+
| `useWindowSize` | `{ width, height }` | Tracks the current width and height of the browser window. |
|
|
541
|
+
|
|
542
|
+
**Examples:**
|
|
543
|
+
|
|
544
|
+
```jsx
|
|
545
|
+
// useHover Example
|
|
546
|
+
import { useHover } from 'app-studio';
|
|
547
|
+
import { View } from './components/View'; // Assuming View component path
|
|
548
|
+
|
|
549
|
+
function HoverComponent() {
|
|
550
|
+
const [hoverRef, isHovered] = useHover();
|
|
551
|
+
return (
|
|
552
|
+
<View ref={hoverRef} padding={20} backgroundColor={isHovered ? 'color.gray.200' : 'color.white'}>
|
|
553
|
+
Hover over me!
|
|
554
|
+
</View>
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// useResponsive Example
|
|
559
|
+
import { useResponsive } from 'app-studio';
|
|
560
|
+
import { View, Text } from './components/Components'; // Assuming component paths
|
|
561
|
+
|
|
562
|
+
function ResponsiveComponent() {
|
|
563
|
+
const { screen, orientation, on } = useResponsive();
|
|
564
|
+
return (
|
|
565
|
+
<View>
|
|
566
|
+
<Text>Current Screen: {screen}, Orientation: {orientation}</Text>
|
|
567
|
+
{on('mobile') && <Text color="color.red.500">This only shows on mobile!</Text>}
|
|
568
|
+
{on('desktop') && <Text color="color.blue.500">This only shows on desktop!</Text>}
|
|
569
|
+
{/* Check specific breakpoint */}
|
|
570
|
+
{on('md') && <Text>Medium screen size detected.</Text>}
|
|
571
|
+
</View>
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// useInView Example
|
|
576
|
+
import { useInView } from 'app-studio';
|
|
577
|
+
import { View, Animation } from './components/Components'; // Assuming component paths
|
|
578
|
+
|
|
579
|
+
function LazyLoadComponent() {
|
|
580
|
+
const { ref, inView } = useInView({ triggerOnce: true, threshold: 0.1 });
|
|
581
|
+
|
|
582
|
+
return (
|
|
583
|
+
<View ref={ref} height={200} backgroundColor="color.gray.100">
|
|
584
|
+
{inView ? (
|
|
585
|
+
<View animate={Animation.fadeIn()}>Content loaded!</View>
|
|
586
|
+
) : (
|
|
587
|
+
'Waiting to scroll into view...'
|
|
588
|
+
)}
|
|
589
|
+
</View>
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
# Providers
|
|
597
|
+
|
|
598
|
+
Providers wrap parts of your application to offer context and global state.
|
|
599
|
+
|
|
600
|
+
## ThemeProvider
|
|
601
|
+
|
|
602
|
+
Manages the application's theme, including color palettes, light/dark modes, and theme tokens.
|
|
603
|
+
|
|
604
|
+
**Props:**
|
|
605
|
+
|
|
606
|
+
| Prop | Type | Default | Description |
|
|
607
|
+
| :------ | :----------------- | :---------------------------------- | :-------------------------------------------------------------------------------- |
|
|
608
|
+
| `theme` | `object` | `{ primary: 'color.black', ... }` | Custom theme tokens (e.g., `primary`, `secondary`) that map to color strings. |
|
|
609
|
+
| `mode` | `'light' \| 'dark'`| `'light'` | Sets the initial theme mode. |
|
|
610
|
+
| `dark` | `Colors` | Default dark palette & main colors | Configuration object for dark mode containing `main` (singleton colors) and `palette`. |
|
|
611
|
+
| `light` | `Colors` | Default light palette & main colors | Configuration object for light mode containing `main` (singleton colors) and `palette`.|
|
|
612
|
+
|
|
613
|
+
**Context Values (via `useTheme`)**
|
|
614
|
+
|
|
615
|
+
* `getColor(colorName, mode?)`: Resolves a color string (e.g., `color.blue.500`, `theme.primary`, `blackAlpha.500`) to its CSS value for the specified or current theme mode.
|
|
616
|
+
* `theme`: The merged theme configuration object.
|
|
617
|
+
* `themeMode`: The current mode ('light' or 'dark').
|
|
618
|
+
* `setThemeMode(mode)`: Function to change the theme mode.
|
|
619
|
+
|
|
620
|
+
## ResponsiveProvider
|
|
621
|
+
|
|
622
|
+
Provides context about the current screen size, orientation, and device type based on configured breakpoints.
|
|
623
|
+
|
|
624
|
+
**Props:**
|
|
625
|
+
|
|
626
|
+
| Prop | Type | Default | Description |
|
|
627
|
+
| :------------ | :----------------- | :---------------------------- | :----------------------------------------------------------------------------------- |
|
|
628
|
+
| `breakpoints` | `ResponsiveConfig` | `{ xs: 0, sm: 340, ... }` | An object mapping breakpoint names (e.g., `xs`, `sm`) to minimum width pixel values. |
|
|
629
|
+
| `devices` | `DeviceConfig` | `{ mobile: ['xs', 'sm'], ...}` | An object mapping device names (e.g., `mobile`) to arrays of breakpoint names. |
|
|
630
|
+
|
|
631
|
+
**Context Values (via `useResponsive`)**
|
|
632
|
+
|
|
633
|
+
* `breakpoints`: The configured breakpoints object.
|
|
634
|
+
* `devices`: The configured devices object.
|
|
635
|
+
* `mediaQueries`: Generated media query strings for each breakpoint.
|
|
636
|
+
* `currentWidth`: Current window width.
|
|
637
|
+
* `currentHeight`: Current window height.
|
|
638
|
+
* `currentBreakpoint`: The name of the currently active breakpoint (e.g., 'sm', 'lg').
|
|
639
|
+
* `currentDevice`: The name of the currently inferred device type (e.g., 'mobile', 'desktop').
|
|
640
|
+
* `orientation`: Current screen orientation ('landscape' or 'portrait').
|
|
641
|
+
* `on(name)` / `is(name)`: Function to check if the current screen matches a breakpoint or device name.
|
|
642
|
+
|
|
643
|
+
## AnalyticsProvider
|
|
644
|
+
|
|
645
|
+
Enables event tracking throughout the application. Components like `Element` automatically track `click` events if `onClick` is provided and this provider is used.
|
|
646
|
+
|
|
647
|
+
**Props:**
|
|
648
|
+
|
|
649
|
+
| Prop | Type | Description |
|
|
650
|
+
| :----------- | :--------- | :---------------------------------------------------------------- |
|
|
651
|
+
| `trackEvent` | `function` | A callback function `(event: { type, target?, text?, ... }) => void` that receives event data to be sent to your analytics service. |
|
|
652
|
+
|
|
653
|
+
**Example Usage (Provider Setup):**
|
|
654
|
+
|
|
655
|
+
See the [Installation](#installation) section.
|
|
656
|
+
|
|
657
|
+
## WindowSizeProvider
|
|
658
|
+
|
|
659
|
+
Provides the current dimensions of the browser window via the `useWindowSize` hook.
|
|
660
|
+
|
|
661
|
+
**Props:** None.
|
|
662
|
+
|
|
663
|
+
**Context Values (via `useWindowSize`)**
|
|
664
|
+
|
|
665
|
+
* `width`: Current window width in pixels.
|
|
666
|
+
* `height`: Current window height in pixels.
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
# Utilities
|
|
671
|
+
|
|
672
|
+
App-Studio exports utility objects and functions.
|
|
673
|
+
|
|
674
|
+
## Colors (`utils/colors.ts`)
|
|
675
|
+
|
|
676
|
+
Defines the default color palettes (`defaultLightPalette`, `defaultDarkPalette`) and singleton colors (`defaultLightColors`, `defaultDarkColors`) used by `ThemeProvider`. You can import these if needed for custom theme configurations. Colors are accessed within components primarily via the `getColor` function from `useTheme`.
|
|
677
|
+
|
|
678
|
+
**Accessing Colors:**
|
|
679
|
+
|
|
680
|
+
```jsx
|
|
681
|
+
import { useTheme } from 'app-studio';
|
|
682
|
+
import { View } from './components/View';
|
|
683
|
+
|
|
684
|
+
function ThemedComponent() {
|
|
685
|
+
const { getColor } = useTheme();
|
|
686
|
+
|
|
687
|
+
return (
|
|
688
|
+
<View
|
|
689
|
+
backgroundColor={getColor('theme.primary')} // Get theme color
|
|
690
|
+
color={getColor('color.white')} // Get singleton color
|
|
691
|
+
borderColor={getColor('color.blue.300')} // Get palette color
|
|
692
|
+
padding={10}
|
|
693
|
+
>
|
|
694
|
+
My Themed Content
|
|
695
|
+
</View>
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
## Typography (`utils/typography.ts`)
|
|
701
|
+
|
|
702
|
+
Exports the `Typography` object containing pre-defined scales for `letterSpacings`, `lineHeights`, `fontWeights`, and `fontSizes`. These are typically used internally or can be referenced when customizing themes.
|
|
703
|
+
|
|
704
|
+
## Shadows (`utils/shadow.ts`)
|
|
705
|
+
|
|
706
|
+
Exports the `Shadows` object, which maps numbers (0-9) to `box-shadow` configurations used by the `shadow` prop on `Element`.
|
|
707
|
+
|
|
708
|
+
## Constants (`utils/constants.ts`)
|
|
709
|
+
|
|
710
|
+
May export various constants used within the library (e.g., internal configuration keys). Check the file for specifics if needed.
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
714
|
+
# Examples
|
|
715
|
+
|
|
716
|
+
## Responsive Layout
|
|
717
|
+
|
|
718
|
+
```jsx
|
|
719
|
+
import { View, Text, useResponsive } from 'app-studio';
|
|
720
|
+
|
|
721
|
+
function ResponsiveCard() {
|
|
722
|
+
const { on } = useResponsive();
|
|
723
|
+
|
|
724
|
+
return (
|
|
725
|
+
<View
|
|
726
|
+
flexDirection={on('mobile') ? 'column' : 'row'} // Stack on mobile, row otherwise
|
|
727
|
+
padding={16}
|
|
728
|
+
backgroundColor="color.white"
|
|
729
|
+
borderRadius={8}
|
|
730
|
+
shadow={2} // Apply shadow level 2
|
|
731
|
+
gap={on('mobile') ? 12 : 20}
|
|
732
|
+
>
|
|
733
|
+
<View flex={1}> {/* Use flex for layout control */}
|
|
734
|
+
<Text fontWeight="bold" fontSize="lg">Card Title</Text>
|
|
735
|
+
<Text color="color.gray.600">Some descriptive content here.</Text>
|
|
736
|
+
</View>
|
|
737
|
+
<View width={on('mobile') ? '100%' : 100} height={100} backgroundColor="color.blue.100" borderRadius={4}>
|
|
738
|
+
{/* Image or placeholder */}
|
|
739
|
+
</View>
|
|
740
|
+
</View>
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
## Animated Button
|
|
746
|
+
|
|
747
|
+
```jsx
|
|
748
|
+
import { Button, Animation } from 'app-studio';
|
|
749
|
+
|
|
750
|
+
function AnimatedButton() {
|
|
751
|
+
return (
|
|
752
|
+
<Button
|
|
753
|
+
paddingHorizontal={20}
|
|
754
|
+
paddingVertical={10}
|
|
755
|
+
backgroundColor="color.green.500"
|
|
756
|
+
color="color.white"
|
|
757
|
+
borderRadius={5}
|
|
758
|
+
fontWeight="bold"
|
|
759
|
+
animate={Animation.fadeIn({ duration: '0.5s' })}
|
|
760
|
+
on={{
|
|
761
|
+
hover: {
|
|
762
|
+
backgroundColor: 'color.green.600',
|
|
763
|
+
animate: Animation.pulse({ duration: '0.8s', iterationCount: 2 })
|
|
764
|
+
},
|
|
765
|
+
active: {
|
|
766
|
+
transform: 'scale(0.95)' // Simple transform on active
|
|
767
|
+
}
|
|
768
|
+
}}
|
|
769
|
+
>
|
|
770
|
+
Click Me
|
|
771
|
+
</Button>
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
---
|
|
777
|
+
|
|
778
|
+
# API Reference Summary
|
|
779
|
+
|
|
780
|
+
* **Core:** `Element`
|
|
781
|
+
* **Components:** `View`, `Horizontal`, `Vertical`, `HorizontalResponsive`, `VerticalResponsive`, `Scroll`, `SafeArea`, `Div`, `Span`, `Text`, `Image`, `ImageBackground`, `Form`, `Input`, `Button`, `Skeleton`.
|
|
782
|
+
* **Animation:** `Animation` object with functions like `fadeIn`, `slideInLeft`, `pulse`, etc.
|
|
783
|
+
* **Hooks:** `useActive`, `useClickOutside`, `useFocus`, `useHover`, `useInView`, `useKeyPress`, `useMount`, `useOnScreen`, `useResponsive`, `useScroll`, `useWindowSize`.
|
|
784
|
+
* **Providers:** `ThemeProvider`, `ResponsiveProvider`, `AnalyticsProvider`, `WindowSizeProvider`.
|
|
785
|
+
* **Context Hooks:** `useTheme`, `useResponsiveContext`, `useAnalytics`, `useWindowSize`.
|
|
786
|
+
* **Utilities:** `colors`, `Typography`, `Shadows`.
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
# Contributing
|
|
791
|
+
|
|
792
|
+
Contributions are welcome! Please follow standard procedures:
|
|
793
|
+
|
|
794
|
+
1. Fork the repository.
|
|
795
|
+
2. Create a feature branch (`git checkout -b feature/your-feature-name`).
|
|
796
|
+
3. Make your changes.
|
|
797
|
+
4. Add tests for your changes.
|
|
798
|
+
5. Commit your changes (`git commit -m 'Add some feature'`).
|
|
799
|
+
6. Push to the branch (`git push origin feature/your-feature-name`).
|
|
800
|
+
7. Open a Pull Request.
|
|
801
|
+
|
|
802
|
+
---
|
|
803
|
+
|
|
804
|
+
# Changelog
|
|
805
|
+
|
|
806
|
+
*(Maintain a log of versions and changes here)*
|
|
807
|
+
|
|
808
|
+
* **vX.Y.Z** (Date):
|
|
809
|
+
* Description of changes.
|
|
810
|
+
* **v1.0.0** (Initial Release):
|
|
811
|
+
* Core `Element` component.
|
|
812
|
+
* Basic components: `View`, `Text`, `Image`, `Form`, `Skeleton`.
|
|
813
|
+
* Hooks for interactions, viewport, and responsiveness.
|
|
814
|
+
* Providers for Theme, Responsiveness, Analytics, WindowSize.
|
|
815
|
+
* Animation system via `Animation` object.
|