unit.gl 0.0.35 → 0.0.39
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/LICENSE +21 -201
- package/README.md +30 -74
- package/css/unit.gl.css +28 -65
- package/css/unit.gl.min.css +1 -1
- package/package.json +13 -8
- package/scss/_global.scss +5 -23
- package/scss/_reset.scss +13 -15
- package/scss/classes/_guide.scss +126 -0
- package/scss/classes/_index.scss +25 -11
- package/scss/classes/_ratio.scss +30 -0
- package/scss/dev/_banner.scss +30 -1
- package/scss/dev/_index.scss +0 -0
- package/scss/functions/_color.scss +40 -0
- package/scss/functions/_index.scss +39 -16
- package/scss/functions/_layer.scss +48 -0
- package/scss/functions/_ratio.scss +58 -157
- package/scss/functions/_scale.scss +55 -49
- package/scss/functions/_sequence.scss +154 -126
- package/scss/functions/_view.scss +40 -0
- package/scss/functions/math/_arithmetic.scss +102 -0
- package/scss/functions/math/_index.scss +30 -0
- package/scss/functions/unit/_index.scss +30 -0
- package/scss/functions/unit/_unit_conversion.scss +94 -0
- package/scss/functions/{_unit_functions.scss → unit/_unit_functions.scss} +70 -36
- package/scss/index.scss +2 -16
- package/scss/maps/_color.scss +43 -0
- package/scss/maps/_index.scss +1 -0
- package/scss/mixins/_device.scss +63 -25
- package/scss/mixins/_display.scss +106 -44
- package/scss/mixins/_guide.scss +191 -158
- package/scss/mixins/_helper.scss +287 -52
- package/scss/mixins/_index.scss +50 -17
- package/scss/mixins/_paper.scss +38 -17
- package/scss/mixins/_ratio.scss +30 -13
- package/scss/mixins/_unit.scss +94 -0
- package/scss/mixins/_view.scss +123 -44
- package/scss/tags/_index.scss +30 -0
- package/scss/tags/_unit.scss +40 -0
- package/scss/utilities/_guides.scss +103 -0
- package/scss/utilities/_index.scss +6 -0
- package/scss/variables/_color.scss +83 -0
- package/scss/variables/_device.scss +140 -50
- package/scss/variables/_index.scss +84 -16
- package/scss/variables/_layer.scss +148 -51
- package/scss/variables/_paper.scss +243 -17
- package/scss/variables/_ratio.scss +224 -0
- package/scss/variables/_scale.scss +230 -104
- package/scss/variables/_unit.scss +76 -72
- package/scss/variables/_view.scss +135 -39
- package/ts/AspectRatio.ts +29 -0
- package/ts/Border.ts +29 -0
- package/ts/BoxModel.ts +40 -0
- package/ts/FlexContainer.ts +48 -0
- package/ts/Grid.ts +21 -0
- package/ts/GridContainer.ts +33 -0
- package/ts/Layout.ts +34 -0
- package/ts/Position.ts +28 -0
- package/ts/Rectangle.ts +28 -0
- package/ts/ResponsiveImage.ts +28 -0
- package/ts/ResponsiveScale.ts +21 -0
- package/ts/Size.ts +32 -0
- package/ts/Spacing.ts +68 -0
- package/ts/Transform.ts +38 -0
- package/ts/Typography.ts +41 -0
- package/ts/Unit.ts +57 -0
- package/ts/Viewport.ts +24 -0
- package/js/index.d.ts +0 -1
- package/js/index.js +0 -3
- package/js/unit.gl.min.js +0 -1
- package/scss/classes/_paper.scss +0 -97
- package/scss/functions/_arithmetic.scss +0 -64
- package/scss/functions/_unit_conversion.scss +0 -77
|
@@ -1,66 +1,162 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Poster
|
|
3
|
+
// ============================================================================
|
|
14
4
|
|
|
5
|
+
////
|
|
6
|
+
///
|
|
7
|
+
/// View Variables Module
|
|
8
|
+
/// ===========================================================================
|
|
9
|
+
///
|
|
10
|
+
/// This module defines the breakpoints for responsive design, categorized by
|
|
11
|
+
/// device types. It leverages a base unit to calculate breakpoint values for
|
|
12
|
+
/// consistency across various screen sizes.
|
|
13
|
+
///
|
|
14
|
+
/// Breakpoint Categories:
|
|
15
|
+
/// - xs: Extra small devices (e.g., Mobile phones)
|
|
16
|
+
/// - sm: Small devices (e.g., Tablets)
|
|
17
|
+
/// - md: Medium devices (e.g., Laptops)
|
|
18
|
+
/// - lg: Large devices (e.g., Desktops)
|
|
19
|
+
/// - xl: Extra large devices (e.g., TVs)
|
|
20
|
+
/// - sl: Super large devices (e.g., Large TVs)
|
|
21
|
+
///
|
|
22
|
+
/// Base Unit:
|
|
23
|
+
/// - The base screen unit is set to 16px, which serves as the foundation for
|
|
24
|
+
/// calculating breakpoints.
|
|
25
|
+
///
|
|
26
|
+
/// Example Usage:
|
|
27
|
+
/// @media (min-width: map-get($breakpoints, md)) {
|
|
28
|
+
/// // Styles for medium devices and up
|
|
29
|
+
/// }
|
|
30
|
+
///
|
|
31
|
+
/// @group View
|
|
32
|
+
/// @author Scape Agency
|
|
33
|
+
/// @link https://unit.gl
|
|
34
|
+
/// @since 0.1.0 initial release
|
|
35
|
+
/// @todo None
|
|
36
|
+
/// @access public
|
|
37
|
+
///
|
|
38
|
+
////
|
|
15
39
|
|
|
16
40
|
|
|
17
41
|
// ============================================================================
|
|
18
|
-
//
|
|
42
|
+
// Use
|
|
19
43
|
// ============================================================================
|
|
20
44
|
|
|
21
|
-
// 320px — 480px: Mobile devices
|
|
22
|
-
// 481px — 768px: iPads, Tablets
|
|
23
|
-
// 769px — 1024px: Small screens, laptops
|
|
24
|
-
// 1025px — 1200px: Desktops, large screens
|
|
25
|
-
// 1201px and more — Extra large screens, TV
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
$base_screen_unit: 16px !default; // Base unit size (16px)
|
|
29
45
|
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Variables
|
|
48
|
+
// ============================================================================
|
|
30
49
|
|
|
31
|
-
@function calc_breakpoint($multiplier) {
|
|
32
|
-
@return $base_screen_unit * $multiplier;
|
|
33
|
-
}
|
|
34
50
|
|
|
51
|
+
///
|
|
52
|
+
/// Base unit size used for calculating breakpoints. Defaults to 16px.
|
|
53
|
+
///
|
|
54
|
+
/// @name $base_screen_unit
|
|
55
|
+
/// @type Length
|
|
56
|
+
///
|
|
57
|
+
$base_screen_unit: 16px !default;
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
///
|
|
62
|
+
/// A map defining the breakpoints for responsive design. Each key represents
|
|
63
|
+
/// a different device category, with the value calculated using the base
|
|
64
|
+
/// screen unit.
|
|
65
|
+
///
|
|
66
|
+
/// - **xs**: 320px (Extra small devices like mobile phones)
|
|
67
|
+
/// - **sm**: 480px (Small devices like tablets)
|
|
68
|
+
/// - **md**: 768px (Medium devices like laptops)
|
|
69
|
+
/// - **lg**: 1024px (Large devices like desktops)
|
|
70
|
+
/// - **xl**: 1280px (Extra large devices like TVs)
|
|
71
|
+
/// - **sl**: 1440px (Super large devices like large TVs)
|
|
72
|
+
///
|
|
73
|
+
/// @name $breakpoints
|
|
74
|
+
/// @type Map
|
|
75
|
+
///
|
|
76
|
+
// $breakpoints: (
|
|
77
|
+
// xs: calc_breakpoint($base_screen_unit, 20), // 320px - Extra small devices (Mobile)
|
|
78
|
+
// sm: calc_breakpoint($base_screen_unit, 30), // 480px - Small devices (Tablets)
|
|
79
|
+
// md: calc_breakpoint($base_screen_unit, 48), // 768px - Medium devices (Laptops)
|
|
80
|
+
// lg: calc_breakpoint($base_screen_unit, 64), // 1024px - Large devices (Desktops)
|
|
81
|
+
// xl: calc_breakpoint($base_screen_unit, 80), // 1280px - Extra large devices (TV)
|
|
82
|
+
// sl: calc_breakpoint($base_screen_unit, 90), // 1440px - Super large devices (Large TV)
|
|
83
|
+
// ) !default;
|
|
35
84
|
|
|
36
|
-
// Define breakpoints using the function
|
|
37
85
|
$breakpoints: (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
86
|
+
xs: 320px, // 320px - Extra small devices (Mobile)
|
|
87
|
+
sm: 480px, // 480px - Small devices (Tablets)
|
|
88
|
+
md: 768px, // 768px - Medium devices (Laptops)
|
|
89
|
+
lg: 1024px, // 1024px - Large devices (Desktops)
|
|
90
|
+
xl: 1280px, // 1280px - Extra large devices (TV)
|
|
91
|
+
sl: 1440px, // 1440px - Super large devices (Large TV)
|
|
44
92
|
) !default;
|
|
45
93
|
|
|
46
94
|
|
|
47
|
-
|
|
95
|
+
///
|
|
96
|
+
/// Exposes the value of the `xs` breakpoint for direct access.
|
|
97
|
+
///
|
|
98
|
+
/// @name $media_xs
|
|
99
|
+
/// @type Length
|
|
100
|
+
///
|
|
48
101
|
$media_xs: map-get($breakpoints, xs) !default;
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
///
|
|
105
|
+
/// Exposes the value of the `sm` breakpoint for direct access.
|
|
106
|
+
///
|
|
107
|
+
/// @name $media_sm
|
|
108
|
+
/// @type Length
|
|
109
|
+
///
|
|
49
110
|
$media_sm: map-get($breakpoints, sm) !default;
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
///
|
|
114
|
+
/// Exposes the value of the `md` breakpoint for direct access.
|
|
115
|
+
///
|
|
116
|
+
/// @name $media_md
|
|
117
|
+
/// @type Length
|
|
118
|
+
///
|
|
50
119
|
$media_md: map-get($breakpoints, md) !default;
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
///
|
|
123
|
+
/// Exposes the value of the `lg` breakpoint for direct access.
|
|
124
|
+
///
|
|
125
|
+
/// @name $media_lg
|
|
126
|
+
/// @type Length
|
|
127
|
+
///
|
|
51
128
|
$media_lg: map-get($breakpoints, lg) !default;
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
///
|
|
132
|
+
/// Exposes the value of the `xl` breakpoint for direct access.
|
|
133
|
+
///
|
|
134
|
+
/// @name $media_xl
|
|
135
|
+
/// @type Length
|
|
136
|
+
///
|
|
52
137
|
$media_xl: map-get($breakpoints, xl) !default;
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
///
|
|
141
|
+
/// Exposes the value of the `sl` breakpoint for direct access.
|
|
142
|
+
///
|
|
143
|
+
/// @name $media_sl
|
|
144
|
+
/// @type Length
|
|
145
|
+
///
|
|
53
146
|
$media_sl: map-get($breakpoints, sl) !default;
|
|
54
147
|
|
|
55
|
-
// $media_xs: 320px !default;
|
|
56
|
-
// $media_sm: 480px !default;
|
|
57
|
-
// $media_md: 768px !default;
|
|
58
|
-
// $media_lg: 1024px !default;
|
|
59
|
-
// $media_xl: 1280px !default;
|
|
60
|
-
// $media_sl: 1440px !default;
|
|
61
148
|
|
|
149
|
+
///
|
|
150
|
+
/// Calculates the difference between the `sl` and `xs` breakpoints.
|
|
151
|
+
///
|
|
152
|
+
/// @name $media_dif
|
|
153
|
+
/// @type Length
|
|
154
|
+
///
|
|
62
155
|
$media_dif: calc($media_sl - $media_xs);
|
|
63
156
|
|
|
157
|
+
|
|
158
|
+
// Uncomment below if you want to use the following predefined breakpoints for various devices:
|
|
159
|
+
|
|
64
160
|
// $media_min: 320px !default; // Mobile
|
|
65
161
|
// $media_med: 640px !default; // Tablet
|
|
66
162
|
// $media_max: 960px !default; // Screen
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class AspectRatio {
|
|
2
|
+
width: Unit;
|
|
3
|
+
height: Unit;
|
|
4
|
+
|
|
5
|
+
constructor(width: Unit, height: Unit) {
|
|
6
|
+
this.width = width;
|
|
7
|
+
this.height = height;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
calculateRatio(): number {
|
|
11
|
+
return this.width.value / this.height.value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
scaleToWidth(newWidth: Unit): Unit {
|
|
15
|
+
const ratio = this.calculateRatio();
|
|
16
|
+
const newHeightValue = newWidth.value / ratio;
|
|
17
|
+
return new Unit(newHeightValue, newWidth.unit);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
scaleToHeight(newHeight: Unit): Unit {
|
|
21
|
+
const ratio = this.calculateRatio();
|
|
22
|
+
const newWidthValue = newHeight.value * ratio;
|
|
23
|
+
return new Unit(newWidthValue, newHeight.unit);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
toString(): string {
|
|
27
|
+
return `AspectRatio: width ${this.width.toString()}, height ${this.height.toString()}, ratio ${this.calculateRatio()}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
package/ts/Border.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type BorderStyle = 'solid' | 'dashed' | 'dotted' | 'double' | 'none';
|
|
2
|
+
|
|
3
|
+
class Border {
|
|
4
|
+
width: Unit;
|
|
5
|
+
style: BorderStyle;
|
|
6
|
+
color: string;
|
|
7
|
+
|
|
8
|
+
constructor(width: Unit, style: BorderStyle, color: string) {
|
|
9
|
+
this.width = width;
|
|
10
|
+
this.style = style;
|
|
11
|
+
this.color = color;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
setWidth(newWidth: Unit): void {
|
|
15
|
+
this.width = newWidth;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setStyle(newStyle: BorderStyle): void {
|
|
19
|
+
this.style = newStyle;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setColor(newColor: string): void {
|
|
23
|
+
this.color = newColor;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
toString(): string {
|
|
27
|
+
return `Border: ${this.width.toString()} ${this.style} ${this.color}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
package/ts/BoxModel.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class BoxModel {
|
|
2
|
+
margin: Margin;
|
|
3
|
+
padding: Padding;
|
|
4
|
+
border: Border;
|
|
5
|
+
size: Size;
|
|
6
|
+
|
|
7
|
+
constructor(margin: Margin, padding: Padding, border: Border, size: Size) {
|
|
8
|
+
if (
|
|
9
|
+
margin.top.unit !== size.width.unit ||
|
|
10
|
+
padding.top.unit !== size.width.unit ||
|
|
11
|
+
border.width.unit !== size.width.unit
|
|
12
|
+
) {
|
|
13
|
+
throw new Error('All units in BoxModel must match');
|
|
14
|
+
}
|
|
15
|
+
this.margin = margin;
|
|
16
|
+
this.padding = padding;
|
|
17
|
+
this.border = border;
|
|
18
|
+
this.size = size;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
setMargin(margin: Margin): void {
|
|
22
|
+
this.margin = margin;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setPadding(padding: Padding): void {
|
|
26
|
+
this.padding = padding;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setBorder(border: Border): void {
|
|
30
|
+
this.border = border;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setSize(size: Size): void {
|
|
34
|
+
this.size = size;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
toString(): string {
|
|
38
|
+
return `BoxModel:\n Size: ${this.size.toString()}\n Margin: ${this.margin.toString()}\n Padding: ${this.padding.toString()}\n Border: ${this.border.toString()}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
type FlexDirection = 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
2
|
+
type FlexWrap = 'nowrap' | 'wrap' | 'wrap-reverse';
|
|
3
|
+
|
|
4
|
+
class FlexContainer {
|
|
5
|
+
flexDirection: FlexDirection;
|
|
6
|
+
flexWrap: FlexWrap;
|
|
7
|
+
justifyContent: Justify;
|
|
8
|
+
alignItems: Align;
|
|
9
|
+
alignContent: Align;
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
flexDirection: FlexDirection = 'row',
|
|
13
|
+
flexWrap: FlexWrap = 'nowrap',
|
|
14
|
+
justifyContent: Justify = 'start',
|
|
15
|
+
alignItems: Align = 'stretch',
|
|
16
|
+
alignContent: Align = 'stretch'
|
|
17
|
+
) {
|
|
18
|
+
this.flexDirection = flexDirection;
|
|
19
|
+
this.flexWrap = flexWrap;
|
|
20
|
+
this.justifyContent = justifyContent;
|
|
21
|
+
this.alignItems = alignItems;
|
|
22
|
+
this.alignContent = alignContent;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setDirection(direction: FlexDirection): void {
|
|
26
|
+
this.flexDirection = direction;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setWrap(wrap: FlexWrap): void {
|
|
30
|
+
this.flexWrap = wrap;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setJustifyContent(justify: Justify): void {
|
|
34
|
+
this.justifyContent = justify;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
setAlignItems(align: Align): void {
|
|
38
|
+
this.alignItems = align;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setAlignContent(align: Align): void {
|
|
42
|
+
this.alignContent = align;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toString(): string {
|
|
46
|
+
return `FlexContainer: direction ${this.flexDirection}, wrap ${this.flexWrap}, justify ${this.justifyContent}, align-items ${this.alignItems}, align-content ${this.alignContent}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
package/ts/Grid.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class Grid {
|
|
2
|
+
columns: number;
|
|
3
|
+
gutter: Unit;
|
|
4
|
+
rowHeight: Unit;
|
|
5
|
+
|
|
6
|
+
constructor(columns: number, gutter: Unit, rowHeight: Unit) {
|
|
7
|
+
this.columns = columns;
|
|
8
|
+
this.gutter = gutter;
|
|
9
|
+
this.rowHeight = rowHeight;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getColumnWidth(containerWidth: Unit): Unit {
|
|
13
|
+
const totalGutterWidth = this.gutter.value * (this.columns - 1);
|
|
14
|
+
const columnWidth = (containerWidth.value - totalGutterWidth) / this.columns;
|
|
15
|
+
return new Unit(columnWidth, containerWidth.unit);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toString(): string {
|
|
19
|
+
return `Grid: ${this.columns} columns, gutter ${this.gutter.toString()}, row height ${this.rowHeight.toString()}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class GridContainer {
|
|
2
|
+
rows: number;
|
|
3
|
+
columns: number;
|
|
4
|
+
rowGap: Unit;
|
|
5
|
+
columnGap: Unit;
|
|
6
|
+
|
|
7
|
+
constructor(rows: number, columns: number, rowGap: Unit, columnGap: Unit) {
|
|
8
|
+
this.rows = rows;
|
|
9
|
+
this.columns = columns;
|
|
10
|
+
this.rowGap = rowGap;
|
|
11
|
+
this.columnGap = columnGap;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
setRows(rows: number): void {
|
|
15
|
+
this.rows = rows;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setColumns(columns: number): void {
|
|
19
|
+
this.columns = columns;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setRowGap(rowGap: Unit): void {
|
|
23
|
+
this.rowGap = rowGap;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setColumnGap(columnGap: Unit): void {
|
|
27
|
+
this.columnGap = columnGap;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
toString(): string {
|
|
31
|
+
return `GridContainer: ${this.rows} rows, ${this.columns} columns, row-gap ${this.rowGap.toString()}, column-gap ${this.columnGap.toString()}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
package/ts/Layout.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type Align = 'start' | 'center' | 'end' | 'stretch';
|
|
2
|
+
type Justify = 'start' | 'center' | 'end' | 'space-between' | 'space-around';
|
|
3
|
+
|
|
4
|
+
class Layout {
|
|
5
|
+
width: Unit;
|
|
6
|
+
height: Unit;
|
|
7
|
+
align: Align;
|
|
8
|
+
justify: Justify;
|
|
9
|
+
direction: 'row' | 'column';
|
|
10
|
+
|
|
11
|
+
constructor(width: Unit, height: Unit, align: Align = 'stretch', justify: Justify = 'start', direction: 'row' | 'column' = 'row') {
|
|
12
|
+
this.width = width;
|
|
13
|
+
this.height = height;
|
|
14
|
+
this.align = align;
|
|
15
|
+
this.justify = justify;
|
|
16
|
+
this.direction = direction;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
setAlign(align: Align): void {
|
|
20
|
+
this.align = align;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setJustify(justify: Justify): void {
|
|
24
|
+
this.justify = justify;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setDirection(direction: 'row' | 'column'): void {
|
|
28
|
+
this.direction = direction;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
toString(): string {
|
|
32
|
+
return `Layout: ${this.direction}, width ${this.width.toString()}, height ${this.height.toString()}, align ${this.align}, justify ${this.justify}`;
|
|
33
|
+
}
|
|
34
|
+
}
|
package/ts/Position.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class Position {
|
|
2
|
+
x: Unit;
|
|
3
|
+
y: Unit;
|
|
4
|
+
|
|
5
|
+
constructor(x: Unit, y: Unit) {
|
|
6
|
+
if (x.unit !== y.unit) {
|
|
7
|
+
throw new Error('X and Y must have the same unit');
|
|
8
|
+
}
|
|
9
|
+
this.x = x;
|
|
10
|
+
this.y = y;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
add(other: Position): Position {
|
|
14
|
+
return new Position(this.x.add(other.x), this.y.add(other.y));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
subtract(other: Position): Position {
|
|
18
|
+
return new Position(this.x.subtract(other.x), this.y.subtract(other.y));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
convert(toUnit: UnitType): Position {
|
|
22
|
+
return new Position(this.x.convert(toUnit), this.y.convert(toUnit));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toString(): string {
|
|
26
|
+
return `Position: (${this.x.toString()}, ${this.y.toString()})`;
|
|
27
|
+
}
|
|
28
|
+
}
|
package/ts/Rectangle.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class Rectangle {
|
|
2
|
+
position: Position;
|
|
3
|
+
size: Size;
|
|
4
|
+
|
|
5
|
+
constructor(position: Position, size: Size) {
|
|
6
|
+
if (position.x.unit !== size.width.unit || position.y.unit !== size.height.unit) {
|
|
7
|
+
throw new Error('Position and Size units must match');
|
|
8
|
+
}
|
|
9
|
+
this.position = position;
|
|
10
|
+
this.size = size;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
move(newPosition: Position): Rectangle {
|
|
14
|
+
return new Rectangle(newPosition, this.size);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
resize(newSize: Size): Rectangle {
|
|
18
|
+
return new Rectangle(this.position, newSize);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
scale(factor: number): Rectangle {
|
|
22
|
+
return new Rectangle(this.position, this.size.scale(factor));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toString(): string {
|
|
26
|
+
return `Rectangle: Position(${this.position.toString()}), Size(${this.size.toString()})`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class ResponsiveImage {
|
|
2
|
+
sources: Map<number, string>; // Map of breakpoint to image URL
|
|
3
|
+
altText: string;
|
|
4
|
+
|
|
5
|
+
constructor(altText: string) {
|
|
6
|
+
this.sources = new Map<number, string>();
|
|
7
|
+
this.altText = altText;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
addSource(breakpoint: number, url: string): void {
|
|
11
|
+
this.sources.set(breakpoint, url);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getSource(viewportWidth: number): string {
|
|
15
|
+
let selectedSource = '';
|
|
16
|
+
this.sources.forEach((url, breakpoint) => {
|
|
17
|
+
if (viewportWidth >= breakpoint) {
|
|
18
|
+
selectedSource = url;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return selectedSource;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
toString(viewportWidth: number): string {
|
|
25
|
+
const source = this.getSource(viewportWidth);
|
|
26
|
+
return `<img src="${source}" alt="${this.altText}" />`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class ResponsiveScale {
|
|
2
|
+
viewport: Viewport;
|
|
3
|
+
baseSize: Unit;
|
|
4
|
+
scaleFactor: number;
|
|
5
|
+
|
|
6
|
+
constructor(viewport: Viewport, baseSize: Unit, scaleFactor: number) {
|
|
7
|
+
this.viewport = viewport;
|
|
8
|
+
this.baseSize = baseSize;
|
|
9
|
+
this.scaleFactor = scaleFactor;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
calculateResponsiveSize(): Unit {
|
|
13
|
+
const ratio = this.viewport.width.value / 1920; // Assuming 1920px is the base
|
|
14
|
+
const scaledValue = this.baseSize.value * Math.pow(this.scaleFactor, ratio);
|
|
15
|
+
return new Unit(scaledValue, this.baseSize.unit);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toString(): string {
|
|
19
|
+
return `ResponsiveScale: Base(${this.baseSize.toString()}) ScaleFactor(${this.scaleFactor}) Viewport(${this.viewport.toString()})`;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/ts/Size.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Size {
|
|
2
|
+
width: Unit;
|
|
3
|
+
height: Unit;
|
|
4
|
+
|
|
5
|
+
constructor(width: Unit, height: Unit) {
|
|
6
|
+
if (width.unit !== height.unit) {
|
|
7
|
+
throw new Error('Width and height must have the same unit');
|
|
8
|
+
}
|
|
9
|
+
this.width = width;
|
|
10
|
+
this.height = height;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
add(other: Size): Size {
|
|
14
|
+
return new Size(this.width.add(other.width), this.height.add(other.height));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
subtract(other: Size): Size {
|
|
18
|
+
return new Size(this.width.subtract(other.width), this.height.subtract(other.height));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
scale(factor: number): Size {
|
|
22
|
+
return new Size(this.width.multiply(factor), this.height.multiply(factor));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
convert(toUnit: UnitType): Size {
|
|
26
|
+
return new Size(this.width.convert(toUnit), this.height.convert(toUnit));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toString(): string {
|
|
30
|
+
return `Size: ${this.width.toString()} x ${this.height.toString()}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
package/ts/Spacing.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
class Spacing {
|
|
2
|
+
top: Unit;
|
|
3
|
+
right: Unit;
|
|
4
|
+
bottom: Unit;
|
|
5
|
+
left: Unit;
|
|
6
|
+
|
|
7
|
+
constructor(top: Unit, right: Unit, bottom: Unit, left: Unit) {
|
|
8
|
+
if (top.unit !== right.unit || top.unit !== bottom.unit || top.unit !== left.unit) {
|
|
9
|
+
throw new Error('All sides must have the same unit');
|
|
10
|
+
}
|
|
11
|
+
this.top = top;
|
|
12
|
+
this.right = right;
|
|
13
|
+
this.bottom = bottom;
|
|
14
|
+
this.left = left;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
add(other: Spacing): Spacing {
|
|
18
|
+
return new Spacing(
|
|
19
|
+
this.top.add(other.top),
|
|
20
|
+
this.right.add(other.right),
|
|
21
|
+
this.bottom.add(other.bottom),
|
|
22
|
+
this.left.add(other.left)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
subtract(other: Spacing): Spacing {
|
|
27
|
+
return new Spacing(
|
|
28
|
+
this.top.subtract(other.top),
|
|
29
|
+
this.right.subtract(other.right),
|
|
30
|
+
this.bottom.subtract(other.bottom),
|
|
31
|
+
this.left.subtract(other.left)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
scale(factor: number): Spacing {
|
|
36
|
+
return new Spacing(
|
|
37
|
+
this.top.multiply(factor),
|
|
38
|
+
this.right.multiply(factor),
|
|
39
|
+
this.bottom.multiply(factor),
|
|
40
|
+
this.left.multiply(factor)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
convert(toUnit: UnitType): Spacing {
|
|
45
|
+
return new Spacing(
|
|
46
|
+
this.top.convert(toUnit),
|
|
47
|
+
this.right.convert(toUnit),
|
|
48
|
+
this.bottom.convert(toUnit),
|
|
49
|
+
this.left.convert(toUnit)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
toString(): string {
|
|
54
|
+
return `Spacing: ${this.top.toString()} ${this.right.toString()} ${this.bottom.toString()} ${this.left.toString()}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
class Margin extends Spacing {
|
|
59
|
+
constructor(top: Unit, right: Unit, bottom: Unit, left: Unit) {
|
|
60
|
+
super(top, right, bottom, left);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class Padding extends Spacing {
|
|
65
|
+
constructor(top: Unit, right: Unit, bottom: Unit, left: Unit) {
|
|
66
|
+
super(top, right, bottom, left);
|
|
67
|
+
}
|
|
68
|
+
}
|
package/ts/Transform.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
type AngleUnit = 'deg' | 'rad';
|
|
2
|
+
|
|
3
|
+
class Transform {
|
|
4
|
+
translateX: Unit;
|
|
5
|
+
translateY: Unit;
|
|
6
|
+
rotate: number;
|
|
7
|
+
rotateUnit: AngleUnit;
|
|
8
|
+
scaleX: number;
|
|
9
|
+
scaleY: number;
|
|
10
|
+
|
|
11
|
+
constructor(translateX: Unit, translateY: Unit, rotate: number, rotateUnit: AngleUnit, scaleX: number, scaleY: number) {
|
|
12
|
+
this.translateX = translateX;
|
|
13
|
+
this.translateY = translateY;
|
|
14
|
+
this.rotate = rotate;
|
|
15
|
+
this.rotateUnit = rotateUnit;
|
|
16
|
+
this.scaleX = scaleX;
|
|
17
|
+
this.scaleY = scaleY;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setTranslation(translateX: Unit, translateY: Unit): void {
|
|
21
|
+
this.translateX = translateX;
|
|
22
|
+
this.translateY = translateY;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setRotation(angle: number, unit: AngleUnit): void {
|
|
26
|
+
this.rotate = angle;
|
|
27
|
+
this.rotateUnit = unit;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setScale(scaleX: number, scaleY: number): void {
|
|
31
|
+
this.scaleX = scaleX;
|
|
32
|
+
this.scaleY = scaleY;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
toString(): string {
|
|
36
|
+
return `Transform: translate(${this.translateX.toString()}, ${this.translateY.toString()}) rotate(${this.rotate}${this.rotateUnit}) scale(${this.scaleX}, ${this.scaleY})`;
|
|
37
|
+
}
|
|
38
|
+
}
|