ds-one 0.1.11-alpha.1 → 0.1.11-alpha.11
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/DS1/0-face/2025-04-23-device.ts +135 -1
- package/DS1/1-root/fonts/GT-America-Compressed-Regular.woff2 +0 -0
- package/DS1/1-root/one.css +16 -2
- package/DS1/2-core/{text-v1.ts → ds-text.ts} +4 -4
- package/DS1/2-core/home-v1.ts +2 -2
- package/DS1/3-unit/doublenav-v1.ts +2 -2
- package/DS1/3-unit/singlenav-v1.ts +1 -1
- package/DS1/4-page/ds-grid.ts +74 -9
- package/DS1/4-page/ds-layout.ts +1 -20
- package/DS1/index.ts +7 -1
- package/DS1/utils/cdn-loader.ts +5 -0
- package/DS1/utils/keys.json +41 -1
- package/README.md +5 -5
- package/dist/0-face/2025-04-23-device.d.ts +24 -0
- package/dist/0-face/2025-04-23-device.d.ts.map +1 -1
- package/dist/0-face/2025-04-23-device.js +94 -1
- package/dist/2-core/ds-text.d.ts +48 -0
- package/dist/2-core/ds-text.d.ts.map +1 -0
- package/dist/2-core/ds-text.js +83 -0
- package/dist/2-core/home-v1.js +2 -2
- package/dist/3-unit/doublenav-v1.js +2 -2
- package/dist/3-unit/singlenav-v1.js +1 -1
- package/dist/4-page/ds-grid.d.ts +7 -0
- package/dist/4-page/ds-grid.d.ts.map +1 -1
- package/dist/4-page/ds-grid.js +69 -9
- package/dist/4-page/ds-layout.d.ts.map +1 -1
- package/dist/4-page/ds-layout.js +1 -20
- package/dist/ds-one.bundle.js +190 -39
- package/dist/ds-one.bundle.js.map +3 -3
- package/dist/ds-one.bundle.min.js +68 -67
- package/dist/ds-one.bundle.min.js.map +4 -4
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/utils/cdn-loader.d.ts.map +1 -1
- package/dist/utils/cdn-loader.js +5 -0
- package/dist/utils/keys.json +41 -1
- package/package.json +1 -1
|
@@ -1,4 +1,138 @@
|
|
|
1
1
|
// 2025-04-23-device.ts
|
|
2
2
|
// Device detection and context utilities
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
export type DeviceType = "mobile" | "tablet" | "desktop";
|
|
5
|
+
|
|
6
|
+
export interface DeviceInfo {
|
|
7
|
+
isMobile: boolean;
|
|
8
|
+
isTablet: boolean;
|
|
9
|
+
isDesktop: boolean;
|
|
10
|
+
isTouchCapable: boolean;
|
|
11
|
+
deviceType: DeviceType;
|
|
12
|
+
userAgent: string;
|
|
13
|
+
screenWidth: number;
|
|
14
|
+
screenHeight: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Comprehensive mobile device detection
|
|
19
|
+
* Combines user agent detection, touch capability, and viewport size
|
|
20
|
+
*/
|
|
21
|
+
export function detectMobileDevice(): boolean {
|
|
22
|
+
if (typeof navigator === "undefined" || typeof window === "undefined") {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const nav = navigator as any;
|
|
27
|
+
const win = window as any;
|
|
28
|
+
const ua: string =
|
|
29
|
+
(nav && (nav.userAgent || nav.vendor)) || (win && win.opera) || "";
|
|
30
|
+
|
|
31
|
+
// User agent based detection
|
|
32
|
+
const uaMatchesMobile =
|
|
33
|
+
/Mobile|Android|iP(ad|hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)|Windows Phone|Phone|Tablet/i.test(
|
|
34
|
+
ua
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Touch capability detection
|
|
38
|
+
const touchPoints = (nav && nav.maxTouchPoints) || 0;
|
|
39
|
+
const isTouchCapable = touchPoints > 1;
|
|
40
|
+
|
|
41
|
+
// Viewport detection
|
|
42
|
+
const narrowViewport = win
|
|
43
|
+
? Math.min(win.innerWidth || 0, win.innerHeight || 0) <= 820
|
|
44
|
+
: false;
|
|
45
|
+
|
|
46
|
+
return uaMatchesMobile || (isTouchCapable && narrowViewport);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get detailed device information
|
|
51
|
+
*/
|
|
52
|
+
export function getDeviceInfo(): DeviceInfo {
|
|
53
|
+
const isMobile = detectMobileDevice();
|
|
54
|
+
const nav = navigator as any;
|
|
55
|
+
const win = window as any;
|
|
56
|
+
|
|
57
|
+
const touchPoints = (nav && nav.maxTouchPoints) || 0;
|
|
58
|
+
const isTouchCapable = touchPoints > 1;
|
|
59
|
+
|
|
60
|
+
const screenWidth = win?.innerWidth || 0;
|
|
61
|
+
const screenHeight = win?.innerHeight || 0;
|
|
62
|
+
const isTablet = isMobile && Math.min(screenWidth, screenHeight) >= 600;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
isMobile,
|
|
66
|
+
isTablet,
|
|
67
|
+
isDesktop: !isMobile,
|
|
68
|
+
isTouchCapable,
|
|
69
|
+
deviceType: isMobile ? (isTablet ? "tablet" : "mobile") : "desktop",
|
|
70
|
+
userAgent: (nav && (nav.userAgent || nav.vendor)) || "",
|
|
71
|
+
screenWidth,
|
|
72
|
+
screenHeight,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Initialize device detection and log to console
|
|
78
|
+
*/
|
|
79
|
+
export function initDeviceDetection(): DeviceInfo {
|
|
80
|
+
const deviceInfo = getDeviceInfo();
|
|
81
|
+
|
|
82
|
+
// Calculate and set scaling factor for mobile
|
|
83
|
+
if (deviceInfo.isMobile && typeof document !== "undefined") {
|
|
84
|
+
// Design width: 280px (14 columns × 20px)
|
|
85
|
+
const designWidth = 280;
|
|
86
|
+
const actualWidth = deviceInfo.screenWidth;
|
|
87
|
+
const scalingFactor = actualWidth / designWidth;
|
|
88
|
+
|
|
89
|
+
// Set CSS custom property for scaling
|
|
90
|
+
document.documentElement.style.setProperty(
|
|
91
|
+
"--scaling-factor-mobile",
|
|
92
|
+
scalingFactor.toFixed(3)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
console.log(
|
|
96
|
+
`[DS one] Mobile device detected - ${deviceInfo.deviceType} (${deviceInfo.screenWidth}x${deviceInfo.screenHeight}), scaling factor: ${scalingFactor.toFixed(2)}`
|
|
97
|
+
);
|
|
98
|
+
} else {
|
|
99
|
+
// Desktop - no scaling
|
|
100
|
+
if (typeof document !== "undefined") {
|
|
101
|
+
document.documentElement.style.setProperty(
|
|
102
|
+
"--scaling-factor-mobile",
|
|
103
|
+
"1"
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
console.log(
|
|
107
|
+
`[DS one] Desktop device detected (${deviceInfo.screenWidth}x${deviceInfo.screenHeight})`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Log additional details in development mode
|
|
112
|
+
if (typeof window !== "undefined" && (window as any).DS_ONE_DEBUG) {
|
|
113
|
+
console.log("[DS one] Device Info:", {
|
|
114
|
+
type: deviceInfo.deviceType,
|
|
115
|
+
isMobile: deviceInfo.isMobile,
|
|
116
|
+
isTablet: deviceInfo.isTablet,
|
|
117
|
+
isDesktop: deviceInfo.isDesktop,
|
|
118
|
+
isTouchCapable: deviceInfo.isTouchCapable,
|
|
119
|
+
viewport: `${deviceInfo.screenWidth}x${deviceInfo.screenHeight}`,
|
|
120
|
+
userAgent: deviceInfo.userAgent,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return deviceInfo;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Auto-initialize when module loads
|
|
128
|
+
if (typeof window !== "undefined") {
|
|
129
|
+
// Wait for DOM to be ready
|
|
130
|
+
if (document.readyState === "loading") {
|
|
131
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
132
|
+
initDeviceDetection();
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
// DOM is already ready
|
|
136
|
+
initDeviceDetection();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
Binary file
|
package/DS1/1-root/one.css
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* version 0.1.11-alpha.8 */
|
|
2
|
+
|
|
1
3
|
input {
|
|
2
4
|
padding: 0;
|
|
3
5
|
}
|
|
@@ -32,9 +34,10 @@ input {
|
|
|
32
34
|
--ds1-docs-search-bg: light-dark(#f0f0f0, #171717);
|
|
33
35
|
--ds1-docs-divider: light-dark(#e0e0e0, #000000);
|
|
34
36
|
|
|
35
|
-
/*
|
|
37
|
+
/* typefaces */
|
|
36
38
|
--typeface: "GT-America-Standard-Regular";
|
|
37
39
|
--typeface-medium: "GT-America-Standard-Medium";
|
|
40
|
+
--typeface-compressed: "GT-America-Compressed-Regular";
|
|
38
41
|
--typeface-japanese: "Noto Sans JP";
|
|
39
42
|
--typeface-mono: "Iosevka";
|
|
40
43
|
--type-size-default: calc(14px * var(--scaling-factor));
|
|
@@ -54,7 +57,7 @@ input {
|
|
|
54
57
|
--type-lineheight-book: 15px;
|
|
55
58
|
|
|
56
59
|
/* ezo-scaling-factor */
|
|
57
|
-
--scaling-factor:
|
|
60
|
+
--scaling-factor: var(--scaling-factor-mobile);
|
|
58
61
|
--scaling-factor-mobile: 1;
|
|
59
62
|
|
|
60
63
|
/* size */
|
|
@@ -149,6 +152,17 @@ html {
|
|
|
149
152
|
font-display: swap;
|
|
150
153
|
}
|
|
151
154
|
|
|
155
|
+
@font-face {
|
|
156
|
+
font-family: GT-America-Compressed-Regular;
|
|
157
|
+
src: url("./fonts/GT-America-Compressed-Regular.woff2") format("woff2");
|
|
158
|
+
font-display: swap;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
body {
|
|
162
|
+
margin: 0;
|
|
163
|
+
padding: 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
152
166
|
.matrix__board {
|
|
153
167
|
position: relative;
|
|
154
168
|
top: calc(21.5px * var(--scaling-factor));
|
|
@@ -4,7 +4,7 @@ import { getText } from "../utils/language";
|
|
|
4
4
|
/**
|
|
5
5
|
* A component for displaying text from translations
|
|
6
6
|
*
|
|
7
|
-
* @element text
|
|
7
|
+
* @element ds-text
|
|
8
8
|
* @prop {string} key - The translation key to use
|
|
9
9
|
* @prop {string} defaultValue - Default value if translation is not found
|
|
10
10
|
* @prop {string} fallback - Optional fallback text if translation is not found (deprecated, use defaultValue)
|
|
@@ -35,7 +35,7 @@ export class Text extends LitElement {
|
|
|
35
35
|
// Create bound event handlers for proper cleanup
|
|
36
36
|
this.boundHandlers = {
|
|
37
37
|
languageChanged: (() => {
|
|
38
|
-
console.log("Language changed event received in text
|
|
38
|
+
console.log("Language changed event received in ds-text");
|
|
39
39
|
this._loadText();
|
|
40
40
|
}) as EventListener,
|
|
41
41
|
};
|
|
@@ -112,10 +112,10 @@ export class Text extends LitElement {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
customElements.define("text
|
|
115
|
+
customElements.define("ds-text", Text);
|
|
116
116
|
|
|
117
117
|
declare global {
|
|
118
118
|
interface HTMLElementTagNameMap {
|
|
119
|
-
"text
|
|
119
|
+
"ds-text": Text;
|
|
120
120
|
}
|
|
121
121
|
}
|
package/DS1/2-core/home-v1.ts
CHANGED
|
@@ -86,7 +86,7 @@ export class Home extends LitElement {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/* Inner text spacing without affecting the 80px outer width */
|
|
89
|
-
.home > text
|
|
89
|
+
.home > ds-text {
|
|
90
90
|
padding: 0 calc(var(--1) * 0.15 * var(--scaling-factor));
|
|
91
91
|
box-sizing: border-box;
|
|
92
92
|
height: 100%;
|
|
@@ -152,7 +152,7 @@ export class Home extends LitElement {
|
|
|
152
152
|
@click="${this._navigateHome}"
|
|
153
153
|
@keydown="${this._onKeyDown}"
|
|
154
154
|
>
|
|
155
|
-
<text
|
|
155
|
+
<ds-text key="home"></ds-text>
|
|
156
156
|
</div>
|
|
157
157
|
`;
|
|
158
158
|
}
|
|
@@ -80,14 +80,14 @@ export class DoubleNav extends LitElement {
|
|
|
80
80
|
? html`
|
|
81
81
|
<a href="${this.previous}" class="nav-previous">
|
|
82
82
|
<icon-v1 type="left"></icon-v1>
|
|
83
|
-
<text
|
|
83
|
+
<ds-text>${this.previousText || "Previous"}</ds-text>
|
|
84
84
|
</a>
|
|
85
85
|
`
|
|
86
86
|
: html`<div></div>`}
|
|
87
87
|
${this.next
|
|
88
88
|
? html`
|
|
89
89
|
<a href="${this.next}" class="nav-next">
|
|
90
|
-
<text
|
|
90
|
+
<ds-text>${this.nextText || "Next"}</ds-text>
|
|
91
91
|
<icon-v1 type="right"></icon-v1>
|
|
92
92
|
</a>
|
|
93
93
|
`
|
package/DS1/4-page/ds-grid.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Simple grid layout component
|
|
3
3
|
|
|
4
4
|
import { LitElement, html, css } from "lit";
|
|
5
|
+
import { detectMobileDevice } from "../0-face/2025-04-23-device";
|
|
5
6
|
|
|
6
7
|
declare global {
|
|
7
8
|
interface CustomElementRegistry {
|
|
@@ -13,26 +14,61 @@ declare global {
|
|
|
13
14
|
export class Grid extends LitElement {
|
|
14
15
|
static properties = {
|
|
15
16
|
align: { type: String },
|
|
17
|
+
_isMobile: { type: Boolean, state: true },
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
align?: string;
|
|
21
|
+
_isMobile: boolean = false;
|
|
22
|
+
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
super.connectedCallback();
|
|
25
|
+
this._isMobile = detectMobileDevice();
|
|
26
|
+
console.log(`[ds-grid] Mobile device: ${this._isMobile}`);
|
|
27
|
+
|
|
28
|
+
// Apply mobile class immediately
|
|
29
|
+
if (this._isMobile) {
|
|
30
|
+
this.classList.add("mobile");
|
|
31
|
+
console.log(`[ds-grid] Mobile class added`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Calculate mobile grid dimensions to fit screen
|
|
35
|
+
if (this._isMobile && typeof window !== "undefined") {
|
|
36
|
+
const screenWidth = window.innerWidth;
|
|
37
|
+
const columns = 14;
|
|
38
|
+
const gap = 0.5;
|
|
39
|
+
|
|
40
|
+
// Calculate column size accounting for gaps between columns
|
|
41
|
+
// Total width = (columns * columnSize) + ((columns - 1) * gap)
|
|
42
|
+
// Therefore: columnSize = (screenWidth - ((columns - 1) * gap)) / columns
|
|
43
|
+
const totalGapWidth = (columns - 1) * gap;
|
|
44
|
+
const columnSize = (screenWidth - totalGapWidth) / columns;
|
|
45
|
+
|
|
46
|
+
console.log(
|
|
47
|
+
`[ds-grid] Mobile grid: ${columns} columns × ${columnSize.toFixed(2)}px + ${totalGapWidth}px gaps = ${screenWidth}px`
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Set custom property for this grid instance
|
|
51
|
+
this.style.setProperty("--mobile-column-size", `${columnSize}px`);
|
|
52
|
+
this.style.setProperty("--mobile-gap", `${gap}px`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
19
55
|
|
|
20
56
|
static styles = css`
|
|
21
57
|
:host {
|
|
22
58
|
margin-top: 0.5px !important;
|
|
23
59
|
margin-left: 0.5px !important;
|
|
24
60
|
display: grid;
|
|
25
|
-
width:
|
|
61
|
+
width: 1440px;
|
|
26
62
|
height: 100%;
|
|
27
63
|
grid-template-columns: repeat(auto-fill, 19px);
|
|
28
64
|
grid-template-rows: repeat(auto-fill, 19px);
|
|
29
65
|
gap: 1px;
|
|
30
|
-
row-rule: 1px solid
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
light-dark(
|
|
34
|
-
|
|
35
|
-
position:
|
|
66
|
+
row-rule: 1px solid light-dark(rgb(147, 147, 147), rgb(147, 147, 147));
|
|
67
|
+
column-rule: 1px solid light-dark(rgb(147, 147, 147), rgb(147, 147, 147));
|
|
68
|
+
outline:
|
|
69
|
+
1px solid light-dark(rgb(147, 147, 147)),
|
|
70
|
+
rgb(147, 147, 147);
|
|
71
|
+
position: fixed;
|
|
36
72
|
top: 0;
|
|
37
73
|
left: 50%;
|
|
38
74
|
transform: translateX(-50%);
|
|
@@ -40,6 +76,25 @@ export class Grid extends LitElement {
|
|
|
40
76
|
z-index: 300;
|
|
41
77
|
}
|
|
42
78
|
|
|
79
|
+
/* DO NOT CHANGE THIS GRID CODE FOR MOBILE. ITS PERFECT FOR MOBILE. */
|
|
80
|
+
:host(.mobile) {
|
|
81
|
+
outline: calc(2px * var(--scaling-factor)) solid rgba(251, 255, 0, 0.9);
|
|
82
|
+
width: calc(100% - calc(1px * var(--scaling-factor)));
|
|
83
|
+
max-width: 100vw;
|
|
84
|
+
margin-left: 0 !important;
|
|
85
|
+
margin-top: 0 !important;
|
|
86
|
+
box-sizing: border-box;
|
|
87
|
+
position: fixed;
|
|
88
|
+
top: calc(0.5px * var(--scaling-factor));
|
|
89
|
+
left: 50%;
|
|
90
|
+
transform: translateX(-50%);
|
|
91
|
+
pointer-events: none;
|
|
92
|
+
z-index: 300;
|
|
93
|
+
gap: calc(1px * var(--scaling-factor));
|
|
94
|
+
grid-template-columns: repeat(14, calc(19px * var(--scaling-factor)));
|
|
95
|
+
grid-template-rows: repeat(auto-fill, calc(19px * var(--scaling-factor)));
|
|
96
|
+
}
|
|
97
|
+
|
|
43
98
|
:host([align="left"]) {
|
|
44
99
|
left: 0;
|
|
45
100
|
transform: none;
|
|
@@ -51,11 +106,21 @@ export class Grid extends LitElement {
|
|
|
51
106
|
}
|
|
52
107
|
|
|
53
108
|
:host([align="right"]) {
|
|
54
|
-
left:
|
|
55
|
-
|
|
109
|
+
left: auto;
|
|
110
|
+
right: 0;
|
|
111
|
+
transform: none;
|
|
56
112
|
}
|
|
57
113
|
`;
|
|
58
114
|
|
|
115
|
+
updated() {
|
|
116
|
+
// Apply mobile class if detected as mobile device
|
|
117
|
+
if (this._isMobile) {
|
|
118
|
+
this.classList.add("mobile");
|
|
119
|
+
} else {
|
|
120
|
+
this.classList.remove("mobile");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
59
124
|
render() {
|
|
60
125
|
return html``;
|
|
61
126
|
}
|
package/DS1/4-page/ds-layout.ts
CHANGED
|
@@ -39,7 +39,7 @@ export class Layout extends LitElement {
|
|
|
39
39
|
". footer ."
|
|
40
40
|
". . .";
|
|
41
41
|
min-height: 600px;
|
|
42
|
-
background-color: rgba(
|
|
42
|
+
background-color: rgba(165, 165, 165, 0.03);
|
|
43
43
|
position: relative;
|
|
44
44
|
width: 100%;
|
|
45
45
|
max-width: 640px;
|
|
@@ -75,10 +75,6 @@ export class Layout extends LitElement {
|
|
|
75
75
|
justify-self: end;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
:host([mode="debug"]) {
|
|
79
|
-
background-color: rgba(200, 114, 114, 0.1);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
78
|
.debug-overlay {
|
|
83
79
|
position: absolute;
|
|
84
80
|
margin-left: -1px;
|
|
@@ -127,7 +123,6 @@ export class Layout extends LitElement {
|
|
|
127
123
|
font-size: 10px;
|
|
128
124
|
font-weight: var(--type-weight-default);
|
|
129
125
|
font-family: var(--typeface);
|
|
130
|
-
background-color: var(--slate);
|
|
131
126
|
color: var(--black);
|
|
132
127
|
border: 1px solid red;
|
|
133
128
|
opacity: 1;
|
|
@@ -135,53 +130,39 @@ export class Layout extends LitElement {
|
|
|
135
130
|
|
|
136
131
|
.debug-square {
|
|
137
132
|
grid-area: square;
|
|
138
|
-
background-color: rgba(255, 0, 0, 0.2);
|
|
139
133
|
}
|
|
140
134
|
|
|
141
135
|
.debug-title {
|
|
142
136
|
grid-area: title;
|
|
143
|
-
background-color: rgba(0, 255, 0, 0.2);
|
|
144
137
|
}
|
|
145
138
|
|
|
146
139
|
.debug-header {
|
|
147
140
|
grid-area: header;
|
|
148
|
-
background-color: rgba(0, 0, 255, 0.2);
|
|
149
141
|
border-color: #0000ff;
|
|
150
142
|
}
|
|
151
143
|
|
|
152
144
|
.debug-projects {
|
|
153
145
|
grid-area: projects;
|
|
154
|
-
background-color: rgba(255, 255, 0, 0.2);
|
|
155
146
|
border-color: #ffff00;
|
|
156
147
|
}
|
|
157
148
|
|
|
158
149
|
.debug-bio {
|
|
159
150
|
grid-area: bio;
|
|
160
|
-
background-color: rgba(255, 0, 255, 0.2);
|
|
161
151
|
border-color: #ff00ff;
|
|
162
152
|
}
|
|
163
153
|
|
|
164
154
|
.debug-nav {
|
|
165
155
|
grid-area: nav;
|
|
166
|
-
background-color: rgba(0, 255, 255, 0.2);
|
|
167
156
|
border-color: #00ffff;
|
|
168
157
|
}
|
|
169
158
|
|
|
170
159
|
.debug-footer {
|
|
171
160
|
grid-area: footer;
|
|
172
|
-
background-color: rgba(255, 165, 0, 0.2);
|
|
173
161
|
border-color: #ffa500;
|
|
174
162
|
}
|
|
175
163
|
|
|
176
|
-
.debug-header {
|
|
177
|
-
grid-area: header;
|
|
178
|
-
background-color: rgba(0, 0, 255, 0.2);
|
|
179
|
-
border-color: #0000ff;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
164
|
.debug-content {
|
|
183
165
|
grid-area: content;
|
|
184
|
-
background-color: rgba(21, 169, 21, 0.57);
|
|
185
166
|
border-color: rgba(71, 231, 71, 0.63);
|
|
186
167
|
}
|
|
187
168
|
`;
|
package/DS1/index.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
// DS one - Main entry point for all components
|
|
2
2
|
// Export all components for easy importing
|
|
3
3
|
|
|
4
|
+
// Initialize device detection (will auto-detect and log on load)
|
|
5
|
+
import "./0-face/2025-04-23-device";
|
|
6
|
+
|
|
4
7
|
// Initialize CDN loader (will auto-load external translations if available)
|
|
5
8
|
import "./utils/cdn-loader";
|
|
6
9
|
|
|
7
10
|
// Core components
|
|
8
11
|
export * from "./2-core/ds-button";
|
|
9
|
-
export * from "./2-core/text
|
|
12
|
+
export * from "./2-core/ds-text";
|
|
10
13
|
export * from "./2-core/icon-v1";
|
|
11
14
|
export * from "./2-core/link-v1";
|
|
12
15
|
export * from "./2-core/cycle-v1";
|
|
@@ -42,3 +45,6 @@ export * from "./utils/viewMode";
|
|
|
42
45
|
export * from "./utils/settings";
|
|
43
46
|
export * from "./utils/pricing";
|
|
44
47
|
export * from "./utils/scroll";
|
|
48
|
+
|
|
49
|
+
// Device detection
|
|
50
|
+
export * from "./0-face/2025-04-23-device";
|
package/DS1/utils/cdn-loader.ts
CHANGED
|
@@ -124,13 +124,16 @@ async function fetchTranslationFile(
|
|
|
124
124
|
source: string
|
|
125
125
|
): Promise<TranslationMap | null> {
|
|
126
126
|
try {
|
|
127
|
+
console.log(`[DS one] Attempting to fetch translations from: ${source}`);
|
|
127
128
|
const response = await fetch(source);
|
|
128
129
|
|
|
129
130
|
if (!response.ok) {
|
|
131
|
+
console.log(`[DS one] Failed to fetch ${source} (${response.status})`);
|
|
130
132
|
return null;
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
const translations = await response.json();
|
|
136
|
+
console.log(`[DS one] Successfully fetched JSON from ${source}`);
|
|
134
137
|
|
|
135
138
|
if (!validateTranslationMap(translations)) {
|
|
136
139
|
console.warn(
|
|
@@ -145,12 +148,14 @@ async function fetchTranslationFile(
|
|
|
145
148
|
return null;
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
console.log(`[DS one] Valid translations found: ${languages.join(", ")}`);
|
|
148
152
|
return translations;
|
|
149
153
|
} catch (error) {
|
|
150
154
|
if (
|
|
151
155
|
error instanceof TypeError &&
|
|
152
156
|
error.message.includes("Failed to fetch")
|
|
153
157
|
) {
|
|
158
|
+
console.log(`[DS one] Network error fetching ${source}`);
|
|
154
159
|
return null;
|
|
155
160
|
}
|
|
156
161
|
|
package/DS1/utils/keys.json
CHANGED
|
@@ -1 +1,41 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"en": {
|
|
3
|
+
"language": "Language",
|
|
4
|
+
"theme": "Theme",
|
|
5
|
+
"home": "Home",
|
|
6
|
+
"about": "About",
|
|
7
|
+
"contact": "Contact",
|
|
8
|
+
"welcome": "Welcome",
|
|
9
|
+
"description": "Description",
|
|
10
|
+
"learnMore": "Learn More",
|
|
11
|
+
"copyright": "© 2025",
|
|
12
|
+
"siteTitle": "Site Title",
|
|
13
|
+
"downloadCV": "Download CV"
|
|
14
|
+
},
|
|
15
|
+
"da": {
|
|
16
|
+
"language": "Sprog",
|
|
17
|
+
"theme": "Tema",
|
|
18
|
+
"home": "Hjem",
|
|
19
|
+
"about": "Om",
|
|
20
|
+
"contact": "Kontakt",
|
|
21
|
+
"welcome": "Velkommen",
|
|
22
|
+
"description": "Beskrivelse",
|
|
23
|
+
"learnMore": "Lær Mere",
|
|
24
|
+
"copyright": "© 2025",
|
|
25
|
+
"siteTitle": "Site Titel",
|
|
26
|
+
"downloadCV": "Download CV"
|
|
27
|
+
},
|
|
28
|
+
"ja": {
|
|
29
|
+
"language": "言語",
|
|
30
|
+
"theme": "テーマ",
|
|
31
|
+
"home": "ホーム",
|
|
32
|
+
"about": "について",
|
|
33
|
+
"contact": "お問い合わせ",
|
|
34
|
+
"welcome": "ようこそ",
|
|
35
|
+
"description": "説明",
|
|
36
|
+
"learnMore": "詳細を見る",
|
|
37
|
+
"copyright": "© 2025",
|
|
38
|
+
"siteTitle": "サイトタイトル",
|
|
39
|
+
"downloadCV": "CVをダウンロード"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Build modern UIs with web components!
|
|
|
6
6
|
|
|
7
7
|
[](https://badge.fury.io/js/ds-one)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
[](https://github.com/Jo4712/ds-one)
|
|
10
10
|
|
|
11
11
|
**DS one** is a modern design system that provides a comprehensive set of reusable UI components built with Web Components. Think "Material Design meets Web Standards"—a simple, accessible component library that works with any framework or vanilla JavaScript.
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ npm install ds-one@alpha
|
|
|
27
27
|
yarn add ds-one@alpha
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
**Note**: Currently published as alpha version `0.1.11-alpha.
|
|
30
|
+
**Note**: Currently published as alpha version `0.1.11-alpha.11`. Use `@alpha` tag to install.
|
|
31
31
|
|
|
32
32
|
### Basic Usage
|
|
33
33
|
|
|
@@ -45,12 +45,12 @@ yarn add ds-one@alpha
|
|
|
45
45
|
></script>
|
|
46
46
|
<script
|
|
47
47
|
type="module"
|
|
48
|
-
src="node_modules/design-system-one/2 Core/text
|
|
48
|
+
src="node_modules/design-system-one/2 Core/ds-text.ts"
|
|
49
49
|
></script>
|
|
50
50
|
</head>
|
|
51
51
|
<body>
|
|
52
52
|
<ds-button variant="primary" key="welcomeButton">Get Started</ds-button>
|
|
53
|
-
<text
|
|
53
|
+
<ds-text variant="heading" key="mainHeading">Welcome to DS one</ds-text>
|
|
54
54
|
</body>
|
|
55
55
|
</html>
|
|
56
56
|
```
|
|
@@ -96,7 +96,7 @@ Try DS one in your browser: **[dsone.dev](https://dsone.dev)** (documentation sl
|
|
|
96
96
|
|
|
97
97
|
### Completed Features
|
|
98
98
|
|
|
99
|
-
- ✅ Core component library (ds-button, text
|
|
99
|
+
- ✅ Core component library (ds-button, ds-text, icon-v1, etc.)
|
|
100
100
|
- ✅ Theming system with accent color support
|
|
101
101
|
- ✅ Internationalization with language keys
|
|
102
102
|
- ✅ Responsive design with mobile scaling
|
|
@@ -1 +1,25 @@
|
|
|
1
|
+
export type DeviceType = "mobile" | "tablet" | "desktop";
|
|
2
|
+
export interface DeviceInfo {
|
|
3
|
+
isMobile: boolean;
|
|
4
|
+
isTablet: boolean;
|
|
5
|
+
isDesktop: boolean;
|
|
6
|
+
isTouchCapable: boolean;
|
|
7
|
+
deviceType: DeviceType;
|
|
8
|
+
userAgent: string;
|
|
9
|
+
screenWidth: number;
|
|
10
|
+
screenHeight: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Comprehensive mobile device detection
|
|
14
|
+
* Combines user agent detection, touch capability, and viewport size
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectMobileDevice(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Get detailed device information
|
|
19
|
+
*/
|
|
20
|
+
export declare function getDeviceInfo(): DeviceInfo;
|
|
21
|
+
/**
|
|
22
|
+
* Initialize device detection and log to console
|
|
23
|
+
*/
|
|
24
|
+
export declare function initDeviceDetection(): DeviceInfo;
|
|
1
25
|
//# sourceMappingURL=2025-04-23-device.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"2025-04-23-device.d.ts","sourceRoot":"","sources":["../../DS1/0-face/2025-04-23-device.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"2025-04-23-device.d.ts","sourceRoot":"","sources":["../../DS1/0-face/2025-04-23-device.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CA0B5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAsB1C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,UAAU,CA8ChD"}
|